﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Forms;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using VAdvantage.Model;
using VAdvantage.Utility;
using VAdvantage.Classes;
using VAdvantage.Grids;
using VAdvantage.Controls;
using VAdvantage.Logging;
using System.Collections;
using System.Text;
using System.Data;
using VAdvantage.DataBase;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Data;
using VAdvantage.Process;


namespace VAdvantage.Apps.AForms
{
    public partial class VAllocation : UserControl, FormPanel
    {
        # region Private Variables
        private int _windowNo = 0;
        private FormFrame _frame;
        private int _C_Currency_ID = 0;
        private VAdvantage.Controls.VTextBoxButton vbPartnerSearch = null;
        private VAdvantage.Controls.VComboBox cmbCurrencyPick;
        //  private VAdvantage.Controls.VStatusBar allocationStatusBar;
        private static VLogger log = VLogger.GetVLogger(typeof(VAllocation).FullName);
        int _C_BPartner_ID = 0;
        ToolTip toolTip = new ToolTip();
        private System.ComponentModel.BackgroundWorker worker;
        private List<int> _bpartnerCheck = new List<int>();
        private int _payment = 7;
        StringBuilder sql = null;
        private int _open = 6;
        private int _discount = 7;
        private int _writeOff = 10;
        private int _applied = 11;
        bool isUpdate = false;
        private bool _calculating = false;
        //  Grid.VComboBox cmbCurrencyPick;
        bool colInvCheck = false;
        bool colPayCheck = false;
        bool colCashCheck = false;

        private int _noInvoices = 0;
        private int _noPayments = 0;
        private int _noCashLines = 0;
        DataGridRow dr = null;
        bool status = false;

        Grids.MyDataGridCheckBoxColumn chk = new MyDataGridCheckBoxColumn();
        Grids.MyDataGridCheckBoxColumn chkCash = new MyDataGridCheckBoxColumn();
        Grids.MyDataGridCheckBoxColumn chkInv = new MyDataGridCheckBoxColumn();

        #endregion


        public VAllocation()
        {

        }

        public void Init(int WindowNo, FormFrame frame)
        {
            InitializeComponent();
            //this.Dock = DockStyle.Fill;
            _windowNo = WindowNo;
            _frame = frame;
            //_frame.Height = App.Current.Host.Content.ActualHeight - 25;
            //_frame.Width = App.Current.Host.Content.ActualWidth;
            Envs.GetCtx().SetContext(_windowNo, "IsSOTrx", "Y");   //  defaults to no
            _C_Currency_ID = Envs.GetCtx().GetContextAsInt("$C_Currency_ID");   //  default
            this.Visibility = System.Windows.Visibility.Visible;
            _frame.ContentGrid.Children.Add(this);
            LayoutRoot.Background = new SolidColorBrush(DataBase.GlobalVariable.WINDOW_BACK_COLOR);
            vbtnAllocate.Click += new RoutedEventHandler(vbtnAllocate_Click);
            chk.Click += new RoutedEventHandler(chk_Click);
            chk.PropertyChanged += new PropertyChangedEventHandler(chk_PropertyChanged);
            chkCash.Click += new RoutedEventHandler(chkCash_Click);
            chkCash.PropertyChanged += new PropertyChangedEventHandler(chkCash_PropertyChanged);
            chkInv.Click += new RoutedEventHandler(chkInv_Click);
            chkInv.PropertyChanged += new PropertyChangedEventHandler(chkInv_PropertyChanged);


            // vbPartnerSearch.VetoableChangeListener+=new EventHandler(vbPartnerSearch_VetoableChangeListener);
            log.Info("Currency=" + _C_Currency_ID);
            try
            {
                DynInit();
                JbInit();
                Calculate();
                //  frame.GetContentPane().Controls.Add((Control)this);
            }
            catch (Exception e)
            {
                log.Log(Level.SEVERE, "", e);
            }

            // frame.Size = new Size(800, 470);
            //CommonFunctions.SetDataGridPrperties(vdgvInvoice);
            // CommonFunctions.SetDataGridPrperties(vdgvPayment);
            //CommonFunctions.SetDataGridPrperties(vdgvCashLine);
            // CommonStyle(vdgvInvoice);
            // CommonStyle(vdgvPayment);
            // CommonStyle(vdgvCashLine);
            vdgvCashLine.IsReadOnly = true;
            vdgvPayment.IsReadOnly = false;

        }

        public void Dispose()
        {

        }


        private void SetBusy(bool value)
        {
            
            this.IsEnabled = !value;
            busyWindow.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
            txtBusy.Visibility = value ? System.Windows.Visibility.Visible : System.Windows.Visibility.Collapsed;
        }

        private void DynInit()
        {
            //  Currency
            int AD_Column_ID = 3505;    //  C_Invoice.C_Currency_ID
            List<NamePair> _data = null;
            SetBusy(true);
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                Lookup lookupCur = MLookupFactory.Get(Envs.GetCtx(), _windowNo, AD_Column_ID, DisplayType.TableDir);
                //cmbCurrencyPick = new VFramework.Grids.VComboBox("C_Currency_ID", true, false, true, lookupCur, 120);
                //cmbCurrencyPick.SetValue(_C_Currency_ID);
                MLookup m = (MLookup)lookupCur;
                _data = m.GetData(true, true, false, false);//here we get all currency active as well as inactive

                AD_Column_ID = 3499;        //  C_Invoice.C_BPartner_ID
                Lookup lookupBP = MLookupFactory.Get(Envs.GetCtx(), _windowNo, AD_Column_ID, DisplayType.Search);
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => FillCombo(_data, lookupBP));
               
            });

        }
        bool checkCombo = false;

        public void FillCombo(List<NamePair> _data, Lookup lookupBP)
        {

            checkCombo = true;
            SetBusy(true);
            cmbCurrencyPick = new VAdvantage.Controls.VComboBox();
            vbPartnerSearch = new VTextBoxButton("C_BPartner_ID", true, false, true, DisplayType.Search, lookupBP);
           
            vdgvInnerGrid.Children.Add(vbPartnerSearch);
            Grid.SetColumn(vbPartnerSearch, 1);
            Grid.SetRow(vbPartnerSearch, 0);
           // vbPartnerSearch.Margin = new Thickness(2);
            //vbPartnerSearch.Width = 135;
            vbPartnerSearch.Height = 21;
            Grid.SetColumnSpan(vbPartnerSearch, 1);

            for (int i = 0; i < _data.Count; i++)
            {
                cmbCurrencyPick.Items.Add(_data[i]);
                if (Util.GetValueOfInt(_data[i].Key) == _C_Currency_ID)
                {
                    cmbCurrencyPick.SelectedIndex = i;
                }
            }




            //allocationStatusBar.SetStatusLine(Msg.GetMsg(Envs.GetCtx(), "AllocateStatus"));





            // allocationStatusBar.SetStatusDB("");

            //  Date set to Login Date
            //vdtpDateField.SetValue(Envs.GetCtx().GetContextAsTime("#Date"));
            vdtpDateField.DateTimeValue = DateTime.Now;

            //vdtpDateField.SetValue(System.DateTime.Now.Date);//.ToString("MM/dd/yyyy"));

            this.vbPartnerSearch.HorizontalAlignment = HorizontalAlignment.Stretch;
            //  this.vbPartnerSearch.AutoSize = true;
            this.vbPartnerSearch.Name = "vbPartnerSearch";
            this.vbPartnerSearch.VetoableChangeListener += new EventHandler(vbPartnerSearch_VetoableChangeListener);
            vdgvInnerGrid.Children.Add(cmbCurrencyPick);
            Grid.SetRow(cmbCurrencyPick, 0);
            Grid.SetColumn(cmbCurrencyPick, 3);
            //cmbCurrencyPick.Margin = new Thickness(2);
            //cmbCurrencyPick.Width = 135;
            cmbCurrencyPick.Height = 21;
            Grid.SetColumnSpan(cmbCurrencyPick, 1);

            //var AddPartner = CreateTextbox(0, 2);
            // LayoutRoot.Children.Add(AddPartner);
            // this.tblpMain.Controls.Add(this.vbPartnerSearch, 2, 0);

            // this.cmbCurrencyPick.Anchor = System.Windows.Forms.AnchorStyles.Left;
            this.cmbCurrencyPick.HorizontalAlignment = HorizontalAlignment.Stretch;
            //  this.cmbCurrencyPick.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
            //this.cmbCurrencyPick.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
            //  this.cmbCurrencyPick.EditingControlRowIndex = 0;
            //  this.cmbCurrencyPick.EditingControlValueChanged = false;
            //   this.cmbCurrencyPick.FireEvent = true;
            //   this.cmbCurrencyPick.Location = new System.Drawing.Point(203, 29);
            this.cmbCurrencyPick.Name = "cmbCurrencyPick";
            //  this.cmbCurrencyPick.RaiseEvent = true;
            //   this.cmbCurrencyPick.Size = new System.Drawing.Size(135, 21);
            this.cmbCurrencyPick.TabIndex = 3;
            //   this.cmbCurrencyPick.Value = null;
            this.cmbCurrencyPick.SelectionChanged += new SelectionChangedEventHandler(cmbCurrencyPick_SelectionChanged);

            SetBusy(false);
            //  this.tblpMain.Controls.Add(this.cmbCurrencyPick, 2, 1);
        }

        ////private void CommonStyle(SLControls.Controls.VDataGrid ctrl)
        ////{
        ////    ctrl.ColumnHeaderHeight = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
        ////    ctrl.Dock = System.Windows.Forms.DockStyle.Fill;
        ////    ctrl.Location = new System.Drawing.Point(0, 48);
        ////    ctrl.Margin = new System.Windows.Forms.Padding(0);
        ////}


        private void JbInit()
        {
          //  Envs.SetBusyIndicator(true);
            vlblDate.Content = Msg.GetMsg(Envs.GetCtx(), "Date");
            vchkAutoWriteOff.IsChecked = false;
            vchkAutoWriteOff.Content = Msg.GetMsg(Envs.GetCtx(), "AutoWriteOff", true);
            ToolTipService.SetToolTip(vchkAutoWriteOff, Msg.GetMsg(Envs.GetCtx(), "AutoWriteOff", false));
            vlblBusinessPartner.Content = Msg.Translate(Envs.GetCtx(), "C_BPartner_ID");

            vlblPayment.Content = (" " + Msg.Translate(Envs.GetCtx(), "C_Payment_ID"));
            vlblInvoice.Content = (" " + Msg.Translate(Envs.GetCtx(), "C_Invoice_ID"));
            vlblCashLines.Content = (" " + Msg.Translate(Envs.GetCtx(), "C_CashLine_ID"));

            vlblInvSum.Content = (".");
            vlblPaySum.Content = (".");
            vlblCashSum.Content = (".");

            vlblDifference.Content = (Msg.GetMsg(Envs.GetCtx(), "Difference"));
            vtxtDifference.Text = ("0");
            vbtnAllocate.Content = (Msg.GetMsg(Envs.GetCtx(), "Process"));
            vlblCurrency.Content = (Msg.Translate(Envs.GetCtx(), "C_Currency_ID"));
            vchkMultiCurrency.Content = (Msg.GetMsg(Envs.GetCtx(), "MultiCurrency"));
            vchkAllocation.Content = Msg.GetMsg(Envs.GetCtx(), "Cash");
            vlblAllocCurrency.Content = ("USD");
         //   Envs.SetBusyIndicator(false);
        }

        private void vdtpDateField_SelectedDateChanged(Object sender, SelectionChangedEventArgs e)
        {

        }

        private void cmbCurrencyPick_SelectionChanged(Object Sender, EventArgs e)
        {
            //VetoableChange(cmbCurrencyPick.GetSelectedText(), cmbCurrencyPick.SelectedValue);
            VetoableChange("C_Currency_ID", ((KeyNamePair)cmbCurrencyPick.SelectedItem).Key);
        }
        
        /// <summary>
        ///  Load Business Partner Info
        ///  - Payments
        ///  - Invoices
        /// </summary>
        private void LoadBPartner()
        {
            if (_C_BPartner_ID == 0 || _C_Currency_ID == 0)
            {
                SetBusy(false);
                return;
            }

            String getDate = null;
            if (vdtpDateField.GetValue() != null)
            {
                getDate = DB.TO_DATE((DateTime)vdtpDateField.GetValue());
            }
            bool chk = (bool)vchkMultiCurrency.IsChecked;
            vdgvPayment.ItemsSource = null;
            vdgvCashLine.ItemsSource = null;
            vdgvInvoice.ItemsSource = null;
            SetBusy(true);
            txtBusy.Text = Msg.GetMsg("Processing");
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                int AD_Role_ID = Envs.GetCtx().GetAD_Role_ID();
                int AD_User_ID = Envs.GetCtx().GetAD_User_ID();
                //List<ArrayList> dataCashLine = new List<ArrayList>();
                //List<ArrayList> dataInvoice = new List<ArrayList>();
                //List<ArrayList> dataPayment = new List<ArrayList>();
                MRole role = MRole.Get(Envs.GetCtx(), AD_Role_ID, AD_User_ID, false);

                log.Config("BPartner=" + _C_BPartner_ID + ", Cur=" + _C_Currency_ID);
                //  Need to have both values


                //	Async BPartner Test
                int key = Util.GetValueOfInt(_C_BPartner_ID);
                if (!_bpartnerCheck.Contains(key))
                {

                    // worker.RunWorkerAsync();
                    //Application.DoEvents();
                    _bpartnerCheck.Add(key);
                }
                #region Create Payment Grid
                /********************************
             *  Load unallocated Payments
             *      1-TrxDate, 2-DocumentNo, (3-Currency, 4-PayAmt,)
             *      5-ConvAmt, 6-ConvOpen, 7-Allocated
             */
                List<ArrayList> data = new List<ArrayList>();
                DataSet dsPayment = new DataSet();
                StringBuilder sql = new StringBuilder("SELECT 'false' as SELECTROW, p.DateTrx as DATE1,p.DocumentNo As DOCUMENTNO,p.C_Payment_ID As C_PAYMENT_ID,"  //  1..3
                    + "c.ISO_Code as ISO_CODE,p.PayAmt AS PAYMENT,"                            //  4..5
                    + "currencyConvert(p.PayAmt ,p.C_Currency_ID ," + _C_Currency_ID + ",p.DateTrx ,p.C_ConversionType_ID ,p.AD_Client_ID ,p.AD_Org_ID ) AS CONVERTEDAMOUNT,"//  6   #1
                    + "currencyConvert(paymentAvailable(C_Payment_ID) ,p.C_Currency_ID ," + _C_Currency_ID + ",p.DateTrx ,p.C_ConversionType_ID ,p.AD_Client_ID ,p.AD_Org_ID) as OPENAMT,"  //  7   #2
                    + "p.MultiplierAP as MULTIPLIERAP, "
                    + "0 as APPLIEDAMT "
                    + "FROM C_Payment_v p"		//	Corrected for AP/AR
                    + " INNER JOIN C_Currency c ON (p.C_Currency_ID=c.C_Currency_ID) "
                    + "WHERE p.IsAllocated='N' AND p.Processed='Y'"
                    + " AND p.C_Charge_ID IS NULL"		//	Prepayments OK
                    + " AND p.C_BPartner_ID=" + _C_BPartner_ID);                   		//      #3
                if (!chk)
                {
                    sql.Append(" AND p.C_Currency_ID=" + _C_Currency_ID);				//      #4
                }
                sql.Append(" ORDER BY p.DateTrx,p.DocumentNo");

                sql = new StringBuilder(role.AddAccessSQL(sql.ToString(), "p", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO));

                log.Fine("PaySQL=" + sql.ToString());
                dsPayment = DB.ExecuteDataset(sql.ToString(), null);
                _payment = 9;

                #endregion

                #region Create CashLine Grid//work here
                /********************************
             *  Load unallocated Cash lines
             *      1-TrxDate, 2-DocumentNo, (3-Currency, 4-PayAmt,)
             *      5-ConvAmt, 6-ConvOpen, 7-Allocated
             */
                DataSet dsCash = new DataSet();
                List<ArrayList> datacash = new List<ArrayList>();
                StringBuilder sqlCash = new StringBuilder("SELECT 'false' as SELECTROW, cn.created as CREATED, cn.receiptno AS RECEIPTNO, cn.c_cashline_id AS C_CASHLINE_ID,"
                + "c.ISO_Code AS ISO_CODE,cn.amount AS AMOUNT, "
                 + "currencyConvert(cn.Amount ,cn.C_Currency_ID ," + _C_Currency_ID + ",cn.Created ,114 ,cn.AD_Client_ID ,cn.AD_Org_ID ) AS CONVERTEDAMOUNT,"//  6   #1cn.amount as OPENAMT,"
                + " cn.amount as OPENAMT,"
      + "cn.MultiplierAP AS MULTIPLIERAP,"
      + "0 as APPLIEDAMT "
       + " from c_cashline_new cn"
                    //+ " from C_CASHLINE_VW cn"
                + " INNER join c_currency c ON (cn.C_Currency_ID=c.C_Currency_ID)"
                + " WHERE cn.IsAllocated   ='N' AND cn.Processed ='Y'"
                + " and cn.cashtype = 'B' and cn.docstatus in ('CO','CL') "
                    // Commented because Against Business Partner there is no charge
                    // + " AND cn.C_Charge_ID  IS Not NULL"
                + " AND cn.C_BPartner_ID=" + _C_BPartner_ID);
                if (!chk)
                {
                    sqlCash.Append(" AND cn.C_Currency_ID=" + _C_Currency_ID);
                }
                sqlCash.Append(" ORDER BY cn.created,cn.receiptno");

                sqlCash = new StringBuilder(role.AddAccessSQL(sqlCash.ToString(), "cn", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO));

                log.Fine("CashSQL=" + sqlCash.ToString());

                try
                {
                    dsCash = DB.ExecuteDataset(sqlCash.ToString(), null);
                }
                catch (Exception ex)
                {
                    log.SaveError(ex.Message, ex);
                }

                //create grid columns**************


                //_payment = chk ? 7 : 5;
                _payment = 9;

                #endregion

                #region Create Invoice Grid
                DataSet dsInvoice = new DataSet();

                //List<ArrayList> dataInvoice = new List<ArrayList>();
                dsInvoice = null;
                StringBuilder sqlInvoice = new StringBuilder("SELECT 'false' as SELECTROW , i.DateInvoiced  as DATE1 ,"
+ "  i.DocumentNo    AS DOCUMENTNO  ,"
+ "  i.C_Invoice_ID AS C_INVOICE_ID,"
+ "  c.ISO_Code AS ISO_CODE    ,"
//+ "  (i.GrandTotal  *i.MultiplierAP) AS CURRENCY    ,"
+ "  (invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID)  *i.MultiplierAP) AS CURRENCY    ,"
                    //+ "currencyConvert(i.GrandTotal  *i.MultiplierAP,i.C_Currency_ID ," + _C_Currency_ID + ",i.DateInvoiced ,i.C_ConversionType_ID ,i.AD_Client_ID ,i.AD_Org_ID ) AS CONVERTED  ,"
 + "currencyConvert(invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID)  *i.MultiplierAP,i.C_Currency_ID ," + _C_Currency_ID + ",i.DateInvoiced ,i.C_ConversionType_ID ,i.AD_Client_ID ,i.AD_Org_ID ) AS CONVERTED  ,"
 + " currencyConvert(invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID),i.C_Currency_ID,100,i.DateInvoiced,i.C_ConversionType_ID,i.AD_Client_ID,i.AD_Org_ID)                                         *i.MultiplierAP AS AMOUNT,"
                    //+ "(currencyConvert(invoiceOpen(C_Invoice_ID,C_InvoicePaySchedule_ID),i.C_Currency_ID ," + _C_Currency_ID + ",i.DateInvoiced ,i.C_ConversionType_ID ,i.AD_Client_ID ,i.AD_Org_ID)) AS AMOUNT ,"
+ "  (currencyConvert(invoiceDiscount(i.C_Invoice_ID ," + getDate + ",C_InvoicePaySchedule_ID),i.C_Currency_ID ," + _C_Currency_ID + ",i.DateInvoiced ,i.C_ConversionType_ID ,i.AD_Client_ID ,i.AD_Org_ID )*i.Multiplier*i.MultiplierAP) AS DISCOUNT ,"
+ "  i.MultiplierAP ,i.docbasetype  ,"
+ "0 as WRITEOFF ,"
+ "0 as APPLIEDAMT"
                     + " FROM C_Invoice_v i"		//  corrected for CM/Split
                     + " INNER JOIN C_Currency c ON (i.C_Currency_ID=c.C_Currency_ID) "
                     + "WHERE i.IsPaid='N' AND i.Processed='Y'"
                     + " AND i.C_BPartner_ID=" + _C_BPartner_ID);                                            //  #5
                if (!chk)
                {
                    sqlInvoice.Append(" AND i.C_Currency_ID=" + _C_Currency_ID);                                   //  #6
                }
                sqlInvoice.Append(" ORDER BY i.DateInvoiced, i.DocumentNo");

                sqlInvoice = new StringBuilder(role.AddAccessSQL(sqlInvoice.ToString(), "i", MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO));

                log.Fine("InvSQL=" + sqlInvoice.ToString());

                dsInvoice = DB.ExecuteDataset(sqlInvoice.ToString(), null);


                //vdgvInvoice.AutoSize = true;
                _open = 7;
                // _discount = chk ? 7 : 5;
                _discount = 8;
                _writeOff = 11;
                _applied = 12;

                #endregion

                //  Calculate Totals
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() => GridBinding(dsPayment, dsInvoice, dsCash));



            });

            Calculate();


        }



        void vdgvInvoice_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
        {
            //e.Cancel = true;
        }


        private void GridBinding(DataSet dsPayment, DataSet dsInvoice, DataSet dsCash)
        {
            #region Create Payment Grid
            //create grid columns**************
            vdgvPayment.ItemsSource = null;
            vdgvPayment.Columns.Clear();
            //1.Select column
            //DataGridCheckBoxColumn chk = new DataGridCheckBoxColumn();
            //// chk.Name = "Select";
            ////chk.TrueValue = "True";
            /////chk.FalseValue = "False";
            //chk.Header = Msg.GetMsg(Envs.GetCtx(), "SELECT");
            //chk.Binding = new System.Windows.Data.Binding("Select");
            //chk.IsReadOnly = false;
            ////  chk.DataPropertyName = "Select";
            ////chk.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            //vdgvPayment.Columns.Add(chk);


            chk.Header = Msg.GetMsg(Envs.GetCtx(), "SELECTROW");
            chk.Binding = new System.Windows.Data.Binding("SELECTROW");
            chk.DataPropertyName = "SELECTROW";
            chk.DataGrid = vdgvInvoice;
            chk.IsThreeState = false;
            chk.IsReadOnly = false;
            // chk.Width = new DataGridLength(0, DataGridLengthUnitType.SizeToCells);

            vdgvPayment.Columns.Add(chk);


            //2.Date
            DataGridTextColumn date = new DataGridTextColumn();
            date.Binding = new System.Windows.Data.Binding("DATE1");
            date.Header = Msg.Translate(Envs.GetCtx(), "DATE");
            // date.DataPropertyName = "Date";
            date.IsReadOnly = true;
            //date.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvPayment.Columns.Add(date);

            //3.DocumentNo
            DataGridTextColumn docNo = new DataGridTextColumn();
            // docNo.Name = "DocumentNo";
            docNo.Header = Util.CleanMnemonic(Msg.Translate(Envs.GetCtx(), "DOCUMENTNO"));
            //docNo.DataPropertyName = "DocumentNo";
            docNo.Binding = new System.Windows.Data.Binding("DOCUMENTNO");
            docNo.IsReadOnly = true;
            // docNo.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvPayment.Columns.Add(docNo);


            if ((bool)vchkMultiCurrency.IsChecked)
            {
                //4.TrxCurrency
                DataGridTextColumn currency = new DataGridTextColumn();
                //  currency.Name = "TrxCurrency";
                currency.Header = Msg.GetMsg(Envs.GetCtx(), "TRXCURRENCY");
                currency.Binding = new System.Windows.Data.Binding("ISO_CODE");
                currency.IsReadOnly = true;
                //currency.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                vdgvPayment.Columns.Add(currency);

                //5. Amount
                DataGridTextColumn amount = new DataGridTextColumn();
                // amount.Name = "Amount";
                amount.Header = Msg.Translate(Envs.GetCtx(), "AMOUNT");
                amount.Binding = new System.Windows.Data.Binding("PAYMENT");
                amount.IsReadOnly = true;
                //amount.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                vdgvPayment.Columns.Add(amount);
            }

            //6. ConvertedAmount
            DataGridTextColumn convertedAmount = new DataGridTextColumn();
            //  convertedAmount.Name = "ConvertedAmount";
            convertedAmount.Header = Msg.GetMsg(Envs.GetCtx(), "CONVERTEDAMOUNT");
            convertedAmount.Binding = new System.Windows.Data.Binding("CONVERTEDAMOUNT");
            convertedAmount.IsReadOnly = true;
            //convertedAmount.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvPayment.Columns.Add(convertedAmount);

            //7. OpenAmt
            DataGridTextColumn openAmt = new DataGridTextColumn();
            //openAmt.Name = "OpenAmt";
            openAmt.Header = Msg.Translate(Envs.GetCtx(), "OPENAMOUNT");
            openAmt.Binding = new System.Windows.Data.Binding("OPENAMT");
            openAmt.IsReadOnly = true;
            //openAmt.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvPayment.Columns.Add(openAmt);

            //8. AppliedAmt
            DataGridTextColumn appliedAmt = new DataGridTextColumn();
            // appliedAmt.Name = "AppliedAmt";
            // appliedAmt.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            appliedAmt.Header = Msg.Translate(Envs.GetCtx(), "AppliedAmount");
            appliedAmt.Binding = new System.Windows.Data.Binding("APPLIEDAMT");
            appliedAmt.IsReadOnly = true;
            vdgvPayment.Columns.Add(appliedAmt);

            if (dsPayment != null)
            {
                BindingSource source = new BindingSource(dsPayment.Tables[0].GetBindableData(new Connector()));
                vdgvPayment.ItemsSource = source;
                //mainDataSet = dsPayment;
            }

            // vdgvPayment.ItemsSource=dataPayment;

            // //  Set Model
            // // DefaultTableModel modelP = new DefaultTableModel(data, columnNames);
            //// vdgvPayment.RowCount = dataPayment.Count;
            // for (int i = 0; i < dataPayment.Count; i++)
            // {

            //     for (int j = 0; j < dataPayment[i].Count; j++)
            //     {
            //         try
            //         {
            //             //vdgvPayment.Rows[i].Cells[j].Value = ((ArrayList)dataPayment[i])[j];
            //              ((BindableObject)((ObservableCollection<object>)vdgvPayment.ItemsSource)[i]).SetValue(vdgvPayment.Columns[j].Header.ToString(), (((ArrayList)dataPayment[i])[j]).ToString());
            //         }
            //         catch { }

            //     }

            //}
            #endregion
            #region create Cash Grid
            vdgvCashLine.ItemsSource = null;
            vdgvCashLine.Columns.Clear();
            ////1.Select column
            //DataGridCheckBoxColumn chkCash = new DataGridCheckBoxColumn();
            ////  chkCash.Name = "Select";
            /////chkCash.TrueValue = "True";
            ////chkCash.FalseValue = "False";
            //chkCash.Header = Msg.GetMsg(Envs.GetCtx(), "SELECT");
            //chkCash.Binding = new System.Windows.Data.Binding("Select");
            //// chkCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            //vdgvCashLine.Columns.Add(chkCash);


            chkCash.Header = Msg.GetMsg(Envs.GetCtx(), "SELECTROW");
            chkCash.Binding = new System.Windows.Data.Binding("SELECTROW");
            chkCash.DataPropertyName = "SELECTROW";
            chkCash.DataGrid = vdgvInvoice;
            chkCash.IsThreeState = false;
            chkCash.IsReadOnly = false;

            vdgvCashLine.Columns.Add(chkCash);


            //2.Date
            DataGridTextColumn dateCash = new DataGridTextColumn();
            //dateCash.Name = "Date";
            dateCash.Header = Msg.Translate(Envs.GetCtx(), "DATE");
            dateCash.Binding = new System.Windows.Data.Binding("CREATED");
            dateCash.IsReadOnly = true;
            //dateCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvCashLine.Columns.Add(dateCash);

            //3.DocumentNo
            DataGridTextColumn docNoCash = new DataGridTextColumn();
            //docNoCash.Name = "ReceiptNo";
            docNoCash.Header = Util.CleanMnemonic(Msg.Translate(Envs.GetCtx(), "RECEIPTNO"));
            docNoCash.Binding = new System.Windows.Data.Binding("RECEIPTNO");
            docNoCash.IsReadOnly = true;
            // docNoCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvCashLine.Columns.Add(docNoCash);


            if ((bool)vchkMultiCurrency.IsChecked)
            {
                //4.TrxCurrency
                DataGridTextColumn currencyCash = new DataGridTextColumn();
                // currencyCash.Name = "TrxCurrency";
                currencyCash.Header = Msg.GetMsg(Envs.GetCtx(), "TRX");
                currencyCash.Binding = new System.Windows.Data.Binding("ISO_CODE");
                currencyCash.IsReadOnly = true;
                //currencyCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                vdgvCashLine.Columns.Add(currencyCash);

                //5. Amount
                DataGridTextColumn amountCash = new DataGridTextColumn();
                // amountCash.Name = "Amount";
                amountCash.Header = Msg.Translate(Envs.GetCtx(), "AMOUNT");
                amountCash.Binding = new System.Windows.Data.Binding("AMOUNT");
                amountCash.IsReadOnly = true;
                //amountCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                vdgvCashLine.Columns.Add(amountCash);
            }

            //6. ConvertedAmount
            DataGridTextColumn convertedAmountCash = new DataGridTextColumn();
            // convertedAmountCash.Name = "ConvertedAmount";
            convertedAmountCash.Header = Msg.GetMsg(Envs.GetCtx(), "Converted");
            convertedAmountCash.Binding = new System.Windows.Data.Binding("CONVERTEDAMOUNT");
            convertedAmountCash.IsReadOnly = true;
            // convertedAmountCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvCashLine.Columns.Add(convertedAmountCash);

            //7. OpenAmt
            DataGridTextColumn openAmtCash = new DataGridTextColumn();
            //openAmtCash.Name = "OpenAmt";
            openAmtCash.Header = Msg.Translate(Envs.GetCtx(), "OPENAMT");
            openAmtCash.Binding = new System.Windows.Data.Binding("OPENAMT");
            openAmtCash.IsReadOnly = true;
            //openAmtCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvCashLine.Columns.Add(openAmtCash);

            //8. AppliedAmt
            DataGridTextColumn appliedAmtCash = new DataGridTextColumn();
            // appliedAmtCash.Name = "AppliedAmt";
            // appliedAmtCash.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            appliedAmtCash.Header = Msg.Translate(Envs.GetCtx(), "AppliedAmount");
            appliedAmtCash.Binding = new System.Windows.Data.Binding("APPLIEDAMT");
            appliedAmtCash.IsReadOnly = true;
            vdgvCashLine.Columns.Add(appliedAmtCash);

            try
            {
                if (dsCash != null)
                {
                    //DataColumn myColumn = new DataColumn("SELECTROW");
                    //myColumn.DataType = typeof(bool);
                    //ds.Tables[0].Columns.Add(myColumn);
                    //ds.Tables[0].Columns["SELECTROW"].Index = 0;

                    // bind grid to dataset values
                    BindingSource sourceCash = new BindingSource(dsCash.Tables[0].GetBindableData(new Connector()));
                    vdgvCashLine.ItemsSource = sourceCash;
                    // mainDataSet = dsCash;
                }
            }
            catch
            {

            }

            //  Set Model
            // DefaultTableModel modelP = new DefaultTableModel(data, columnNames);
            // vdgvCashLine.RowCount = dataCashLine.Count;
            //for (int i = 0; i < dataCashLine.Count; i++)
            //{

            //    for (int j = 0; j < dataCashLine[i].Count; j++)
            //    {
            //        try
            //        {
            //            vdgvCashLine.Rows[i].Cells[j].Value = ((ArrayList)dataCashLine[i])[j];
            //        }
            //        catch 
            //        { 

            //        }

            //    }

            //}
            #endregion
            #region Create Invoice Grid

            vdgvInvoice.ItemsSource = null;
            vdgvInvoice.Columns.Clear();
            // 1.Select column
            // DataGridCheckBoxColumn chkInv = new DataGridCheckBoxColumn();
            // //chkInv.Name = "Select";
            // //chkInv.TrueValue = "True";
            // //chkInv.FalseValue = "False";
            // chkInv.Header = Msg.GetMsg(Envs.GetCtx(), "SELECTROW");
            // chkInv.Binding = new System.Windows.Data.Binding("SELECTROW");
            // chkInv.IsReadOnly = false;
            //// chkInv.Click += new RoutedEventHandler(chkInv_Click);
            // //chkInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            // vdgvInvoice.Columns.Add(chkInv);



            chkInv.Header = Msg.GetMsg(Envs.GetCtx(), "SELECTROW");
            chkInv.Binding = new System.Windows.Data.Binding("SELECTROW");
            chkInv.DataPropertyName = "SELECTROW";
            chkInv.DataGrid = vdgvInvoice;
            chkInv.IsThreeState = false;
            chkInv.IsReadOnly = false;

            vdgvInvoice.Columns.Add(chkInv);

            //2.Date
            DataGridTextColumn dateInv = new DataGridTextColumn();
            //  dateInv.Name = "Date";
            dateInv.Header = Msg.Translate(Envs.GetCtx(), "Date");
            dateInv.Binding = new System.Windows.Data.Binding("DATE1");
            dateInv.IsReadOnly = true;
            //dateInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(dateInv);

            //3.DocumentNo
            DataGridTextColumn docNoInv = new DataGridTextColumn();
            //docNoInv.Name = "DocumentNo";
            docNoInv.IsReadOnly = true;
            docNoInv.Header = Util.CleanMnemonic(Msg.Translate(Envs.GetCtx(), "DocumentNo"));
            docNoInv.Binding = new System.Windows.Data.Binding("DOCUMENTNO");
            //docNoInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(docNoInv);


            if ((bool)vchkMultiCurrency.IsChecked)
            {
                //4.TrxCurrency
                DataGridTextColumn currency = new DataGridTextColumn();
                // currency.Name = "TrxCurrency";
                currency.IsReadOnly = true;
                currency.Header = Msg.GetMsg(Envs.GetCtx(), "Trx");
                currency.Binding = new System.Windows.Data.Binding("ISO_CODE");
                //currency.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                vdgvInvoice.Columns.Add(currency);

                //5. Amount
                DataGridTextColumn amount = new DataGridTextColumn();
                //amount.Name = "Amount";
                amount.IsReadOnly = true;
                amount.Header = Msg.Translate(Envs.GetCtx(), "Amount");
                amount.Binding = new System.Windows.Data.Binding("CURRENCY");
                //amount.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                vdgvInvoice.Columns.Add(amount);
            }

            //6. ConvertedAmount
            DataGridTextColumn convertedAmountInv = new DataGridTextColumn();
            //convertedAmountInv.Name = "ConvertedAmount";
            convertedAmountInv.Header = Msg.GetMsg(Envs.GetCtx(), "Converted");
            convertedAmountInv.Binding = new System.Windows.Data.Binding("CONVERTED");
            convertedAmountInv.IsReadOnly = true;
            //convertedAmountInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(convertedAmountInv);

            //7. OpenAmt
            DataGridTextColumn openAmtInv = new DataGridTextColumn();
            //openAmtInv.Name = "OpenAmt";
            openAmtInv.Header = Msg.Translate(Envs.GetCtx(), "OpenAmount");
            openAmtInv.IsReadOnly = true;
            openAmtInv.Binding = new System.Windows.Data.Binding("AMOUNT");
            //openAmtInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(openAmtInv);



            DataGridTextColumn docBaseType = new DataGridTextColumn();
            //openAmtInv.Name = "OpenAmt";
            docBaseType.Header = Msg.Translate(Envs.GetCtx(), "DocBaseType");
            docBaseType.IsReadOnly = true;
            docBaseType.Binding = new System.Windows.Data.Binding("docbasetype");
            //openAmtInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            docBaseType.Visibility = Visibility.Collapsed;
            vdgvInvoice.Columns.Add(docBaseType);

            //8. Discount
            DataGridTextColumn discountInv = new DataGridTextColumn();
            //discountInv.Name = "Discount";
            discountInv.Header = Msg.Translate(Envs.GetCtx(), "Discount");
            discountInv.Binding = new System.Windows.Data.Binding("DISCOUNT");
            discountInv.IsReadOnly = true;
            ///discountInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(discountInv);

            //9. WriteOff
            DataGridTextColumn writeOff = new DataGridTextColumn();
            // writeOff.Name = "WriteOff";
            writeOff.Header = Msg.Translate(Envs.GetCtx(), "WriteOff");
            writeOff.Binding = new System.Windows.Data.Binding("WRITEOFF");
            writeOff.IsReadOnly = true;
            //writeOff.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(writeOff);

            //10. AppliedAmt
            DataGridTextColumn appliedAmtInv = new DataGridTextColumn();
            // appliedAmtInv.Name = "AppliedAmt";
            appliedAmtInv.Header = Msg.Translate(Envs.GetCtx(), "AppliedAmount");
            appliedAmtInv.Binding = new System.Windows.Data.Binding("APPLIEDAMT");
            appliedAmtInv.IsReadOnly = true;
            //appliedAmtInv.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
            vdgvInvoice.Columns.Add(appliedAmtInv);

            if (dsInvoice != null)
            {
                for (int i = 0; i < dsInvoice.Tables[0].Rows.Count; i++)
                {
                    if ((bool)vchkMultiCurrency.IsChecked)
                    {

                        if (dsInvoice.Tables[0].Rows[i]["docbasetype"].ToString().ToUpper() == "APC" || dsInvoice.Tables[0].Rows[i]["docbasetype"].ToString().ToUpper() == "ARC")
                        {
                            dsInvoice.Tables[0].Rows[i][5] = VAdvantage.Utility.Util.GetValueOfDecimal(dsInvoice.Tables[0].Rows[i][5]);
                        }
                    }
                    if (dsInvoice.Tables[0].Rows[i]["docbasetype"].ToString().ToUpper() == "APC" || dsInvoice.Tables[0].Rows[i]["docbasetype"].ToString().ToUpper() == "ARC")
                    {
                        dsInvoice.Tables[0].Rows[i][6] = VAdvantage.Utility.Util.GetValueOfDecimal(dsInvoice.Tables[0].Rows[i][6]);
                    }
                    if (dsInvoice.Tables[0].Rows[i]["docbasetype"].ToString().ToUpper() == "APC" || dsInvoice.Tables[0].Rows[i]["docbasetype"].ToString().ToUpper() == "ARC")
                    {
                        dsInvoice.Tables[0].Rows[i][7] = VAdvantage.Utility.Util.GetValueOfDecimal(dsInvoice.Tables[0].Rows[i][7]);
                    }

                }


                BindingSource sourceInvoice = new BindingSource(dsInvoice.Tables[0].GetBindableData(new Connector()));
                vdgvInvoice.ItemsSource = sourceInvoice;
            }

            #endregion
            SetBusy(false);

            vdgvInvoice.BeginningEdit += new EventHandler<DataGridBeginningEditEventArgs>(vdgvInvoice_BeginningEdit);
        }

        void chkCash_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //sthrow new NotImplementedException();
        }

        void chkCash_Click(object sender, RoutedEventArgs e)
        {
            BindingSource rowSource = vdgvCashLine.ItemsSource as BindingSource;
            if (vdgvCashLine.IsReadOnly)
                return;
            if (vdgvCashLine.CurrentColumn.DisplayIndex == 0)
            {
                bool boolValue = GetBoolValue(vdgvCashLine, vdgvCashLine.SelectedIndex, vdgvCashLine.CurrentColumn.DisplayIndex);
                if (boolValue)
                {
                    ((BindableObject)((BindingSource)vdgvCashLine.ItemsSource)[vdgvCashLine.SelectedIndex]).SetValue("SELECTROW", "false");
                    //((BindableObject)((ObservableCollection<object>)vdgvCashLine.ItemsSource)[vdgvCashLine.SelectedIndex]).SetValue("SELECTROW", "false");
                    vdgvCashLine.Columns[ColumnIndex(vdgvCashLine, "AppliedAmount")].IsReadOnly = true;
                    //vdgvCashLine.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = false;
                    //vdgvCashLine.Rows[e.RowIndex].Cells["AppliedAmt"].ReadOnly = true;
                }
                else
                {
                    ((BindableObject)((BindingSource)vdgvCashLine.ItemsSource)[vdgvCashLine.SelectedIndex]).SetValue("SELECTROW", "true");
                    //((BindableObject)((ObservableCollection<object>)vdgvCashLine.ItemsSource)[vdgvCashLine.SelectedIndex]).SetValue("SELECTROW", "true");
                    vdgvCashLine.Columns[ColumnIndex(vdgvCashLine, "AppliedAmount")].IsReadOnly = false;

                    //vdgvCashLine.Rows[e.RowIndex].Cells[e.ColumnIndex].Value = true;
                    //vdgvCashLine.Rows[e.RowIndex].Cells["AppliedAmt"].ReadOnly = false;
                }
                isUpdate = true;
                TableChanged(vdgvCashLine.SelectedIndex, vdgvCashLine.CurrentColumn.DisplayIndex, true, true);
                //     TableChanged(vdgvCashLine.CurrentRow.Index, vdgvCashLine.CurrentColumn.DisplayIndex, true, true);
                isUpdate = false;
            }
        }

        void chk_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            //throw new NotImplementedException();
        }

        void chk_Click(object sender, RoutedEventArgs e)
        {
            IList list = vdgvPayment.SelectedItems;
            if (vdgvPayment.IsReadOnly)
                return;
            //IList rowSource = vdgvInvoice.ItemsSource as IList;
            ////int discountIndex = 0;
            if (vdgvPayment.CurrentColumn.DisplayIndex == 0)
            {
                bool boolValue = GetBoolValue(vdgvPayment, vdgvPayment.SelectedIndex, vdgvPayment.CurrentColumn.DisplayIndex);
                //    //bool boolValue = false;
                if (boolValue)
                {
                    //((BindableObject)vdgvPayment.SelectedItem).SetValue("SELECTROW", "false");
                    // ((BindableObject)vdgvPayment.SelectedItem).SetValue("SELECTROW", "false");
                    ((BindableObject)((BindingSource)vdgvPayment.ItemsSource)[vdgvPayment.SelectedIndex]).SetValue("SELECTROW", "false");
                    vdgvPayment.Columns[ColumnIndex(vdgvPayment, "AppliedAmount")].IsReadOnly = true;
                }
                else
                {
                    // ((BindableObject)vdgvPayment.SelectedItem).SetValue("SELECTROW", "true");
                    ((BindableObject)((BindingSource)vdgvPayment.ItemsSource)[vdgvPayment.SelectedIndex]).SetValue("SELECTROW", "true");
                    vdgvPayment.Columns[ColumnIndex(vdgvPayment, "AppliedAmount")].IsReadOnly = false;
                }
                //else if (((BindableObject)list[0]).GetValue("SELECTROW") == "false")
                //{
                //    ((BindableObject)vdgvInvoice.SelectedItem).SetValue("SELECTROW", "true");
                //    //mainDataSet.Tables[0].Rows[vdgvInvoice.SelectedIndex]["SELECTROW"] = "true";
                //}
                isUpdate = true;
                TableChanged(vdgvPayment.SelectedIndex, vdgvPayment.CurrentColumn.DisplayIndex, false, false);
                //    // TableChanged(vdgvInvoice.CurrentRow.Index, vdgvInvoice.CurrentColumn.DisplayIndex, true, false);
                isUpdate = false;
            }
        }

        void chkInv_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {

        }

        void chkInv_Click(object sender, RoutedEventArgs e)
        {
            IList list = vdgvInvoice.SelectedItems;
            BindingSource rowInvoice = vdgvInvoice.ItemsSource as BindingSource;
            //IList rowSource = vdgvInvoice.ItemsSource as IList;
            ////int discountIndex = 0;
            if (vdgvInvoice.CurrentColumn.DisplayIndex == 0)
            {
                bool boolValue = GetBoolValue(vdgvInvoice, vdgvInvoice.SelectedIndex, vdgvInvoice.CurrentColumn.DisplayIndex);
                //    //bool boolValue = false;
                if (boolValue)
                {
                    //((BindableObject)vdgvInvoice.SelectedItem).SetValue("SELECTROW", "false");
                    ((BindableObject)((BindingSource)vdgvInvoice.ItemsSource)[vdgvInvoice.SelectedIndex]).SetValue("SELECTROW", "false");
                    vdgvInvoice.Columns[ColumnIndex(vdgvInvoice, "Discount %")].IsReadOnly = true;
                    vdgvInvoice.Columns[ColumnIndex(vdgvInvoice, "WriteOff")].IsReadOnly = true;
                    vdgvInvoice.Columns[ColumnIndex(vdgvInvoice, "AppliedAmount")].IsReadOnly = true;
                    //if (((BindableObject)list[0]).GetValue("SELECTROW") == "true")
                    //{
                    //    ((BindableObject)vdgvInvoice.SelectedItem).SetValue("SELECTROW", "false");
                    //    //mainDataSet.Tables[0].Rows[vdgvInvoice.SelectedIndex]["SELECTROW"] = "false";
                    //}
                }
                else
                {
                    // ((BindableObject)vdgvInvoice.SelectedItem).SetValue("SELECTROW", "true");
                    ((BindableObject)((BindingSource)vdgvInvoice.ItemsSource)[vdgvInvoice.SelectedIndex]).SetValue("SELECTROW", "true");
                    vdgvInvoice.Columns[ColumnIndex(vdgvInvoice, "Discount %")].IsReadOnly = false;
                    vdgvInvoice.Columns[ColumnIndex(vdgvInvoice, "WriteOff")].IsReadOnly = false;
                    vdgvInvoice.Columns[ColumnIndex(vdgvInvoice, "AppliedAmount")].IsReadOnly = false;

                }
                //else if (((BindableObject)list[0]).GetValue("SELECTROW") == "false")
                //{
                //    ((BindableObject)vdgvInvoice.SelectedItem).SetValue("SELECTROW", "true");
                //    //mainDataSet.Tables[0].Rows[vdgvInvoice.SelectedIndex]["SELECTROW"] = "true";
                //}
                isUpdate = true;
                TableChanged(vdgvInvoice.SelectedIndex, vdgvInvoice.CurrentColumn.DisplayIndex, true, false);
                //    // TableChanged(vdgvInvoice.CurrentRow.Index, vdgvInvoice.CurrentColumn.DisplayIndex, true, false);
                isUpdate = false;
            }
        }

        public void TableChanged(int rowIndex, int colIndex, bool isInvoice, bool cash)
        {

            BindingSource rowInvoice = vdgvInvoice.ItemsSource as BindingSource;
            BindingSource rowPayment = vdgvPayment.ItemsSource as BindingSource;
            BindingSource rowCash = vdgvCashLine.ItemsSource as BindingSource;
            //  Not a table update
            if (!isUpdate)
            {
                Calculate();
                return;
            }

            //Setting defaults
            if (_calculating)  //  Avoid recursive calls
                return;
            _calculating = true;
            int row = rowIndex;
            int col = colIndex;


            log.Config("Row=" + row + ", Col=" + col + ", InvoiceTable=" + isInvoice);


            //  Payments
            if (!isInvoice)
            {
                //TableModel payment = vdgvInvoice.getModel();
                if (col == 0)
                {
                    colPayCheck = GetBoolValue(vdgvPayment, row, col);
                    //  selected - set payment amount
                    if (colPayCheck)
                    {
                        // Decimal amount = Util.GetValueOfDecimal(vdgvPayment.Rows[row].Cells[_open].Value);  
                        Decimal amount = Util.GetValueOfDecimal(((BindableObject)rowPayment[row]).GetValue(_open));//  OpenAmount
                        //////////
                        //vdgvPayment.Rows[row].Cells[_payment].Value = amount;
                        ((BindableObject)rowPayment[row]).SetValue(_payment, amount.ToString());
                    }
                    else    //  de-selected
                    {
                        // vdgvPayment.Rows[row].Cells[_payment].Value = Envs.ZERO;
                        ((BindableObject)rowPayment[row]).SetValue(_payment, Envs.ZERO.ToString());
                    }
                }
            }
            //Cash Lines
            else if (cash)
            {

                if (col == 0)
                {
                    colCashCheck = GetBoolValue(vdgvCashLine, row, col);
                    //  selected - set payment amount
                    if (colCashCheck)
                    {
                        //Decimal amount = Util.GetValueOfDecimal(vdgvCashLine.Rows[row].Cells[_open].Value);   //  OpenAmount

                        Decimal amount = Util.GetValueOfDecimal(((BindableObject)rowCash[row]).GetValue(_open));

                        // vdgvCashLine.Rows[row].Cells[_payment].Value = amount;
                        //************************************** Changed
                        ((BindableObject)rowCash[row]).SetValue(_payment, amount.ToString());
                    }
                    else    //  de-selected
                    {
                        //vdgvCashLine.Rows[row].Cells[_payment].Value = Envs.ZERO;
                        //************************************** Changed
                        ((BindableObject)rowCash[row]).SetValue(_payment, Envs.ZERO.ToString());
                    }
                }
            }

            //  Invoice Selection
            else if (col == 0)
            {
                colInvCheck = GetBoolValue(vdgvInvoice, row, col);
                //  selected - set applied amount
                if (colInvCheck)
                {
                    //Decimal amount = Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_open].Value);    //  OpenAmount
                    Decimal amount = Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_open));

                    //  amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(vdgvPayment.Columns[_discount].GetCellContent(vdgvPayment.SelectedItem)));
                    amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_discount)));
                    //invoice.setValueAt(Envs.ZERO, row, _writeOff);     //  to be sure
                    //invoice.setValueAt(amount, row, _applied);


                    //vdgvInvoice.Rows[row].Cells[_writeOff].Value = Envs.ZERO;
                    //vdgvInvoice.Rows[row].Cells[_applied].Value = amount;
                    ((BindableObject)rowInvoice[row]).SetValue(_writeOff, Envs.ZERO.ToString());
                    ((BindableObject)rowInvoice[row]).SetValue(_applied, amount.ToString());
                }
                else    //  de-selected
                {
                    //invoice.setValueAt(Envs.ZERO, row, _writeOff);
                    //invoice.setValueAt(Envs.ZERO, row, _applied);


                    //vdgvInvoice.Rows[row].Cells[_writeOff].Value = Envs.ZERO;
                    //vdgvInvoice.Rows[row].Cells[_applied].Value = Envs.ZERO;
                    ((BindableObject)rowInvoice[row]).SetValue(_writeOff, Envs.ZERO.ToString());
                    ((BindableObject)rowInvoice[row]).SetValue(_applied, Envs.ZERO.ToString());

                }
                // vdgvPayment.repaint(); //  update r/o//uncomment it
            }

        //  Invoice - Try to balance entry
            else if ((bool)vchkAutoWriteOff.IsChecked)
            {
                //  if applied entered, adjust writeOff
                if (col == _applied)
                {
                    //  Decimal openAmount = Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_open].Value);    //  OpenAmount

                    Decimal openAmount = Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_open));
                    //Decimal amount = Decimal.Subtract(openAmount, Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_discount].Value));
                    Decimal amount = Decimal.Subtract(openAmount, Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_discount)));

                    //amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_applied].Value));
                    amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_applied)));
                    // /vdgvInvoice.Rows[row].Cells[_writeOff].Value = amount;
                    ((BindableObject)rowInvoice[row]).SetValue(_writeOff, amount.ToString());
                    //	Warning if > 30%
                    if (Convert.ToDouble(amount) / Convert.ToDouble(openAmount) > .30)
                    {
                        ShowMessage.Warn("AllocationWriteOffWarn", null, "", "");
                    }
                }
                else    //  adjust applied
                {
                    // Decimal amount = Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_open].Value);    //  OpenAmount
                    // amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_discount].Value));
                    // amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(vdgvInvoice.Rows[row].Cells[_writeOff].Value));
                    //vdgvInvoice.Rows[row].Cells[_applied].Value = amount;

                    Decimal amount = Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_open));    //  OpenAmount
                    amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_discount)));
                    amount = Decimal.Subtract(amount, Util.GetValueOfDecimal(((BindableObject)rowInvoice[row]).GetValue(_writeOff)));
                    ((BindableObject)rowInvoice[row]).SetValue(_applied, amount.ToString());
                }
            }

            _calculating = false;
            Calculate();
        }

        private void Calculate()
        {
            log.Config("");
            //
            //DecimalFormat format = DisplayType.GetNumberFormat(DisplayType.Amount);
            Format format = DisplayType.GetNumberFormat(DisplayType.Amount);
            DateTime? allocDate = null;

            //  Payment******************
            #region Payment Section
            Decimal totalPay = new Decimal(0.0);
            //int rows = vdgvPayment.ItemsSource.OfType<object>().Count();
            _noPayments = 0;
            BindingSource rowsPayment = null;
            BindingSource rowsCash = null;
            BindingSource rowsInvoice = null;
            //Dispatcher.BeginInvoke(delegate
            //{
            rowsPayment = vdgvPayment.ItemsSource as BindingSource;
            rowsCash = vdgvCashLine.ItemsSource as BindingSource;
            rowsInvoice = vdgvInvoice.ItemsSource as BindingSource;

            //});
            if (rowsPayment != null)
            {
                for (int i = 0; i < rowsPayment.Count; i++)
                {
                    bool boolValue = GetBoolValue(vdgvPayment, i, 0);
                    if (boolValue)
                    {
                        // DateTime? ts = Util.GetValueOfDateTime(vdgvPayment.Rows[i].Cells[1].Value);
                        DateTime? ts = Util.GetValueOfDateTime(Convert.ToDateTime(((BindableObject)rowsPayment[i]).GetValue(1)));

                        //DateTime? ts = Util.GetValueOfDateTime(vdgvPayment.Columns[1].GetCellContent((object)mainDataSet.Tables[0].Rows[i].ToString()).ToString());
                        allocDate = TimeUtil.Max(allocDate, ts);

                        Decimal bd = Util.GetValueOfDecimal(((BindableObject)rowsPayment[i]).GetValue(_payment));
                        totalPay = Decimal.Add(totalPay, bd);  //  Applied Pay
                        _noPayments++;
                        log.Fine("Payment_" + i + " = " + bd + " - Total=" + totalPay);
                    }
                }
            }
            vlblPaySum.Content = (_noPayments.ToString() + " - "
                + Msg.GetMsg(Envs.GetCtx(), "Sum") + "  " + format.GetFormatedValue(totalPay) + " ");
            #endregion

            //  Cash******************
            #region Cash Section
            Decimal totalCash = new Decimal(0.0);
            //rows = vdgvCashLine.ItemsSource.OfType<object>().Count();
            _noCashLines = 0;
            if (rowsCash != null)
            {
                for (int i = 0; i < rowsCash.Count; i++)
                {
                    bool boolValue = GetBoolValue(vdgvCashLine, i, 0);
                    if (boolValue)
                    {
                        DateTime? ts = Util.GetValueOfDateTime(((BindableObject)rowsCash[i]).GetValue(1));
                        allocDate = TimeUtil.Max(allocDate, ts);
                        //************************************** Changed
                        //Decimal bd = Util.GetValueOfDecimal(((BindableObject)rowsCash[i]).GetValue(_payment));
                        Decimal bd = Util.GetValueOfDecimal(((BindableObject)rowsCash[i]).GetValue(_payment));
                        totalCash = Decimal.Add(totalCash, bd);  //  Applied Pay
                        _noCashLines++;
                        log.Fine("Payment_" + i + " = " + bd + " - Total=" + totalCash);
                    }
                }
            }
            vlblCashSum.Content = (_noCashLines.ToString() + " - "
                + Msg.GetMsg(Envs.GetCtx(), "Sum") + "  " + format.GetFormatedValue(totalCash) + " ");
            #endregion


            //  Invoices******************
            #region Invoice Section
            Decimal totalInv = new Decimal(0.0);
            //rows = vdgvInvoice.ItemsSource.OfType<object>().Count();
            _noInvoices = 0;
            if (rowsInvoice != null)
            {
                for (int i = 0; i < rowsInvoice.Count; i++)
                {
                    bool boolValue = GetBoolValue(vdgvInvoice, i, 0);
                    if (boolValue)
                    {
                        DateTime? ts = Util.GetValueOfDateTime(Convert.ToDateTime(((BindableObject)rowsInvoice[i]).GetValue(1)));
                        allocDate = TimeUtil.Max(allocDate, ts);
                        Decimal bd;
                        if (((BindableObject)rowsInvoice[i]).GetValue(_applied) != "")
                        {
                            bd = Util.GetValueOfDecimal(Convert.ToDecimal(((BindableObject)rowsInvoice[i]).GetValue(_applied)));
                        }
                        else
                        {
                            bd = 0;
                        }
                        totalInv = Decimal.Add(totalInv, bd);  //  Applied Inv
                        _noInvoices++;
                        log.Fine("Invoice_" + i + " = " + bd + " - Total=" + totalPay);
                    }
                }
            }
            vlblInvSum.Content = _noInvoices.ToString() + " - "
                + Msg.GetMsg(Envs.GetCtx(), "Sum") + "  " + format.GetFormatedValue(totalInv) + " ";

            #endregion

            //	Set AllocationDate
            if (allocDate != null)
                vdtpDateField.SetValue(allocDate);
            //if (checkCombo)
            //{
            //  Set Allocation Currency
            if (cmbCurrencyPick.GetText() != null)
            {
                vlblAllocCurrency.Content = cmbCurrencyPick.GetText(); //.getDisplay());
            }
            // }
            //  Difference 
            //Decimal difference = Decimal.Subtract(totalPay, totalInv);
            //  Difference --New Logic for Invoice-(cash+payment)-by raghu 18-jan-2011 //  Cash******************
            Decimal difference = Decimal.Subtract(Decimal.Add(totalPay, totalCash), totalInv);

            vtxtDifference.Text = format.GetFormatedValue(difference);
            if (difference.CompareTo(new Decimal(0.0)) == 0)
            {
                vbtnAllocate.IsEnabled = true;
            }
            else
            {
                vbtnAllocate.IsEnabled = false;
            }
            //s SetBusy(false);
        }

        private bool GetBoolValue(DataGrid grid, int row, int col)
        {
            List<DataGridRow> Rows = new List<DataGridRow>();
            bool boolValue = false;
            BindingSource rowSource = grid.ItemsSource as BindingSource;
            //if (Grids.SelectedIndex >= 0)
            //{
            //    foreach (var rowItem in Grids.ItemsSource)
            //    {

            //        FrameworkElement el = Grids.Columns.Last().GetCellContent(rowItem);
            //        DataGridRow row1 = DataGridRow.GetRowContainingElement(el.Parent as FrameworkElement);

            //        if (row1 != null)
            //            Rows.Add(row1);
            //    }
            //    DataGridRow dr = Rows[Grids.SelectedIndex];
            //    //if (Grids.Columns[col].GetCellContent(dr).ToString() == "true")
            //    if(((CheckBox)Grids.Columns[col].GetCellContent(dr)).IsChecked.ToString().ToUpper()=="TRUE")
            if (((BindableObject)rowSource[row]).GetValue(col) == "true" || ((BindableObject)rowSource[row]).GetValue(col) == "True")
            {
                boolValue = true;
                // / SetBusy(false);
            }
            else
            {
                boolValue = false;
                //   SetBusy(false);
            }

            //if (ctl.Rows[row].Cells[col].Value.ToString() == "True")

            //{
            //    boolValue = true;
            //}
            //else
            //{
            //    boolValue = false;
            //}
            return boolValue;
        }

        /**
        *  Vetoable Change Listener.
        *  - Business Partner
        *  - Currency
        * 	- Date
        *  @param e event
        */

        public void VetoableChange(String name, Object value)
        {
            //String name = e.getPropertyName();
            //Object value = e.getNewValue();
            log.Config(name + "=" + value);
            if (value == null)
            {
                SetBusy(false);
                return;
            }

            //  BPartner
            if (name.Equals("C_BPartner_ID"))
            {
                vbPartnerSearch.SetValue(value);
                _C_BPartner_ID = Util.GetValueOfInt(value);
                LoadBPartner();
            }
            //	Currency
            else if (name.Equals("C_Currency_ID"))
            {
                _C_Currency_ID = Util.GetValueOfInt(value);
                LoadBPartner();
            }
            //	Date for Multi-Currency
            else if (name.Equals("Date") && ((bool)vchkMultiCurrency.IsChecked))
                LoadBPartner();
        }

        /// <summary>
        /// Save Data
        /// </summary>

        private void SaveData(BindingSource rowsPayment, BindingSource rowsCash, BindingSource rowsInvoice, DateTime? DateTrx)
        {
            //IList rowsPayment = vdgvPayment.ItemsSource as IList;
            //IList rowsCash = vdgvCashLine.ItemsSource as IList;
            //IList rowsInvoice = vdgvInvoice.ItemsSource as IList;
            // DateTime? DateTrx = Util.GetValueOfDateTime(vdtpDateField.GetValue());

            if (_noInvoices + _noPayments + _noCashLines == 0)
                return;

            //  fixed fields
            int AD_Client_ID = Envs.GetCtx().GetContextAsInt(_windowNo, "AD_Client_ID");
            int AD_Org_ID = Envs.GetCtx().GetContextAsInt(_windowNo, "AD_Org_ID");
            int C_BPartner_ID = _C_BPartner_ID;
            int C_Order_ID = 0;
            int C_CashLine_ID = 0;
            //  DateTime? DateTrx = Util.GetValueOfDateTime(vdtpDateField.GetValue());
            int C_Currency_ID = _C_Currency_ID;	//	the allocation currency
            //
            if (AD_Org_ID == 0)
            {
                Classes.ShowMessage.Error("Org0NotAllowed", null);
                return;
            }
            //
            log.Config("Client=" + AD_Client_ID + ", Org=" + AD_Org_ID
                + ", BPartner=" + C_BPartner_ID + ", Date=" + DateTrx);

            Trx trx = Trx.Get(Trx.CreateTrxName("AL"), true);

            /**
             * Generation of allocations:               amount/discount/writeOff
             *  - if there is one payment -- one line per invoice is generated
             *    with both the Invoice and Payment reference
             *      Pay=80  Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#1
             *    or
             *      Pay=160 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#1
             *      Pay=160 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#2
             *
             *  - if there are multiple payment lines -- the amounts are allocated
             *    starting with the first payment and payment
             *      Pay=60  Inv=100 Disc=10 WOff=10 =>  60/10/10    Pay#1   Inv#1
             *      Pay=100 Inv=100 Disc=10 WOff=10 =>  20/0/0      Pay#2   Inv#1
             *      Pay=100 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#2   Inv#2
             *
             *  - if you apply a credit memo to an invoice
             *              Inv=10  Disc=0  WOff=0  =>  10/0/0              Inv#1
             *              Inv=-10 Disc=0  WOff=0  =>  -10/0/0             Inv#2
             *
             *  - if you want to write off a (partial) invoice without applying,
             *    enter zero in applied
             *              Inv=10  Disc=1  WOff=9  =>  0/1/9               Inv#1
             *  Issues
             *  - you cannot write-off a payment
             */


            //  Payment - Loop and Add them to paymentList/amountList
            #region Payment-Loop
            //int pRows = vdgvPayment.ItemsSource.OfType<object>().Count();
            // IList rowsPayment = vdgvPayment.ItemsSource as IList;

            List<int> paymentList = new List<int>(rowsPayment.Count);
            List<Decimal> amountList = new List<Decimal>(rowsPayment.Count);
            Decimal paymentAppliedAmt = Envs.ZERO;
            // bool boolValue=false;              
            for (int i = 0; i < rowsPayment.Count; i++)
            {
                //  Payment line is selected

                bool boolValue = false;
                bool flag = false;
                Dispatcher.BeginInvoke(delegate
                {
                    boolValue = GetBoolValue(vdgvPayment, i, 0);
                    flag = true;
                });
                while (!flag)
                {
                    System.Threading.Thread.Sleep(1);
                }
                if (boolValue)
                {
                    // KeyNamePair pp = (KeyNamePair)vdgvPayment.Rows[i].Cells[2].Value;   //  Value

                    //  Payment variables
                    int C_Payment_ID = Util.GetValueOfInt(((BindableObject)rowsPayment[i]).GetValue("C_PAYMENT_ID"));
                    paymentList.Add(C_Payment_ID);
                    //
                    //Decimal PaymentAmt = Util.GetValueOfDecimal(vdgvPayment.Rows[i].Cells[_payment].Value);  //  Applied Payment
                    Decimal PaymentAmt = Util.GetValueOfDecimal(((BindableObject)rowsPayment[i]).GetValue(_payment));  //  Applied Payment
                    amountList.Add(PaymentAmt);
                    //
                    paymentAppliedAmt = Decimal.Add(paymentAppliedAmt, PaymentAmt);
                    //
                    log.Fine("C_Payment_ID=" + C_Payment_ID
                        + " - PaymentAmt=" + PaymentAmt); // + " * " + Multiplier + " = " + PaymentAmtAbs);
                }
            }


            log.Config("Number of Payments=" + paymentList.Count + " - Total=" + paymentAppliedAmt);
            #endregion

            //  CashLines - Loop and Add them to cashList/CashAmountList
            #region CashLines-Loop
            //int cRows = vdgvCashLine.ItemsSource.OfType<object>().Count();
            //IList rowsCash = vdgvCashLine.ItemsSource as IList;
            if (rowsCash != null)
            {
                List<int> cashList = new List<int>(rowsCash.Count);
                List<Decimal> CashAmtList = new List<Decimal>(rowsCash.Count);
                Decimal cashAppliedAmt = Envs.ZERO;

                for (int i = 0; i < rowsCash.Count; i++)
                {
                    //  Payment line is selected
                    bool boolValue = false;
                    bool flag = false;
                    Dispatcher.BeginInvoke(delegate
                    {
                        boolValue = GetBoolValue(vdgvCashLine, i, 0);
                        flag = true;
                    });
                    while (!flag)
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                    if (boolValue)
                    {
                        // KeyNamePair pp = (KeyNamePair)((BindableObject)rowsCash[i]).GetValue(2);   //  Value
                        //  Payment variables
                        C_CashLine_ID = Util.GetValueOfInt(((BindableObject)rowsCash[i]).GetValue("C_CASHLINE_ID"));
                        cashList.Add(C_CashLine_ID);
                        //
                        //  Decimal PaymentAmt = Util.GetValueOfDecimal(vdgvCashLine.Rows[i].Cells[_payment].Value);  //  Applied Payment
                        Decimal PaymentAmt = Util.GetValueOfDecimal(((BindableObject)rowsCash[i]).GetValue(_payment));  //  Applied Payment
                        CashAmtList.Add(PaymentAmt);
                        //
                        cashAppliedAmt = Decimal.Add(cashAppliedAmt, PaymentAmt);
                        //
                        log.Fine("C_CashLine_ID=" + C_CashLine_ID
                            + " - PaymentAmt=" + PaymentAmt); // + " * " + Multiplier + " = " + PaymentAmtAbs);
                    }
                }

                log.Config("Number of Payments=" + paymentList.Count + " - Total=" + cashAppliedAmt);
            }
            #endregion

            //  Invoices - Loop and generate alloctions
            #region Invoice-Loop with allocation
            // int iRows = vdgvInvoice.ItemsSource.OfType<object>().Count();
            // IList rowsInvoice = vdgvInvoice.ItemsSource as IList;
            Decimal totalAppliedAmt = Envs.ZERO;

            //	Create Allocation - but don't save ye
            MAllocationHdr alloc = new MAllocationHdr(Envs.GetCtx(), true,	//	manual
DateTrx, C_Currency_ID, Envs.GetCtx().GetContext("#AD_User_Name"), trx.GetTrxName());
            alloc.SetAD_Org_ID(AD_Org_ID);


            //	For all invoices
            int invoiceLines = 0;


            for (int i = 0; i < rowsInvoice.Count; i++)
            {
                //  Invoice line is selected
                bool boolValue = false;
                bool flag = false;
                Dispatcher.BeginInvoke(delegate
                {
                    boolValue = GetBoolValue(vdgvInvoice, i, 0);
                    flag = true;
                });
                while (!flag)
                {
                    System.Threading.Thread.Sleep(1);
                }

                if (boolValue)
                {
                    invoiceLines++;
                    //KeyNamePair pp = (KeyNamePair)((BindableObject)rowsCash[i]).GetValue(2);    //  Value
                    //  Invoice variables
                    int C_Invoice_ID = Util.GetValueOfInt(((BindableObject)rowsInvoice[i]).GetValue("C_INVOICE_ID"));
                    //Decimal AppliedAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_applied].Value);
                    Decimal AppliedAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_applied));
                    //  semi-fixed fields (reset after first invoice)
                    // Decimal DiscountAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_discount].Value);
                    // Decimal WriteOffAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_writeOff].Value);

                    Decimal DiscountAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_discount));
                    Decimal WriteOffAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_writeOff));
                    //	OverUnderAmt needs to be in Allocation Currency
                    // Decimal OverUnderAmt = Decimal.Subtract(Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_open].Value),
                    //  Decimal.Subtract(AppliedAmt, Decimal.Subtract(DiscountAmt, WriteOffAmt)));

                    Decimal OverUnderAmt = Decimal.Subtract(Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_open)),
                        Decimal.Subtract(AppliedAmt, Decimal.Subtract(DiscountAmt, WriteOffAmt)));

                    log.Config("Invoice #" + i + " - AppliedAmt=" + AppliedAmt);// + " -> " + AppliedAbs);

                    //Payment Settelment**********
                    //  loop through all payments until invoice applied
                    int noPayments = 0;
                    for (int j = 0; j < paymentList.Count && Envs.Signum(AppliedAmt) != 0; j++)
                    {
                        int C_Payment_ID = Util.GetValueOfInt(paymentList[j]);
                        Decimal PaymentAmt = Util.GetValueOfDecimal(amountList[j]);
                        if (Envs.Signum(PaymentAmt) != 0)
                        {
                            log.Config(".. with payment #" + j + ", Amt=" + PaymentAmt);
                            noPayments++;
                            //  use Invoice Applied Amt
                            Decimal amount = AppliedAmt;
                            log.Fine("C_Payment_ID=" + C_Payment_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                + ", Amount=" + amount + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                            ///Allocation header

                            //  Apply Discounts and WriteOff only first time
                            DiscountAmt = Envs.ZERO;
                            WriteOffAmt = Envs.ZERO;
                            //  subtract amount from Payment/Invoice
                            AppliedAmt = Decimal.Subtract(AppliedAmt, amount);
                            //AppliedAmt = Decimal.Subtract(PaymentAmt, AppliedAmt);
                            PaymentAmt = Decimal.Subtract(PaymentAmt, amount);
                            log.Fine("Allocation Amount=" + amount + " - Remaining  Applied=" + AppliedAmt + ", Payment=" + PaymentAmt);

                            //amountList.set(j, PaymentAmt);  //  update
                            amountList[j] = PaymentAmt;  //  update//set

                        }	//	for all applied amounts
                    }	//	loop through payments for invoice


                    //CashLines settelment************
                    //  loop through all payments until invoice applied
                    int noCashlines = 0;
                    if (rowsCash != null)
                    {
                        List<int> cashList = new List<int>(rowsCash.Count);
                        List<Decimal> CashAmtList = new List<Decimal>(rowsCash.Count);
                        Decimal cashAppliedAmt = Envs.ZERO;
                        for (int j = 0; j < cashList.Count && Envs.Signum(AppliedAmt) != 0; j++)
                        {
                            C_CashLine_ID = Util.GetValueOfInt(cashList[j]);
                            Decimal PaymentAmt = Util.GetValueOfDecimal(CashAmtList[j]);
                            if (Envs.Signum(PaymentAmt) != 0)
                            {
                                log.Config(".. with payment #" + j + ", Amt=" + PaymentAmt);
                                noCashlines++;
                                //  use Invoice Applied Amt
                                Decimal amount = AppliedAmt;
                                log.Fine("C_CashLine_ID=" + C_CashLine_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                    + ", Amount=" + amount + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                                //	Allocation Header
                                if (alloc.Get_ID() == 0 && !alloc.Save())
                                {
                                    log.Log(Level.SEVERE, "Allocation not created");
                                    trx.Rollback();
                                    trx.Close();
                                    return;
                                }
                                //	Allocation Line
                                MAllocationLine aLine = new MAllocationLine(alloc, amount,
                                    DiscountAmt, WriteOffAmt, OverUnderAmt);
                                aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                                aLine.SetPaymentInfo(0, C_CashLine_ID);//payment for payment allocation is zero
                                if (!aLine.Save())
                                    log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                                //  Apply Discounts and WriteOff only first time
                                DiscountAmt = Envs.ZERO;
                                WriteOffAmt = Envs.ZERO;
                                //  subtract amount from Payment/Invoice
                                AppliedAmt = Decimal.Subtract(AppliedAmt, amount);
                                //AppliedAmt = Decimal.Subtract(PaymentAmt, AppliedAmt);
                                PaymentAmt = Decimal.Subtract(PaymentAmt, amount);
                                log.Fine("Allocation Amount=" + amount + " - Remaining  Applied=" + AppliedAmt + ", Payment=" + PaymentAmt);

                                //amountList.set(j, PaymentAmt);  //  update
                                if (CashAmtList.Count > 0)
                                    CashAmtList[j] = PaymentAmt;  //  update//set

                            }	//	for all applied amounts
                        }
                    }	//	loop through Cash for invoice(Charge)


                    //  No Payments allocated and none existing (e.g. Inv/CM)
                    if (rowsPayment.Count > 0)
                        if (noPayments == 0 && paymentList.Count == 0)
                        {
                            int C_Payment_ID = 0;
                            log.Config(" ... no payment - TotalApplied=" + totalAppliedAmt);
                            //  Create Allocation
                            log.Fine("C_Payment_ID=" + C_Payment_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                + ", Amount=" + AppliedAmt + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                            //	Allocation Header
                            if (alloc.Get_ID() == 0 && !alloc.Save())
                            {
                                log.Log(Level.SEVERE, "Allocation not created");
                                trx.Rollback();
                                trx.Close();
                                return;
                            }
                            //	Allocation Line
                            MAllocationLine aLine = new MAllocationLine(alloc, AppliedAmt,
                                DiscountAmt, WriteOffAmt, OverUnderAmt);
                            aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                            //aLine.SetPaymentInfo(C_Payment_ID, C_CashLine_ID);
                            aLine.SetPaymentInfo(C_Payment_ID, 0);
                            if (!aLine.Save(trx.GetTrxName()))
                                log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                            log.Fine("Allocation Amount=" + AppliedAmt);
                        }


                    //  No Cashlines allocated and none existing 
                    if (rowsCash != null)
                    {
                        List<Decimal> cashList = new List<Decimal>(rowsCash.Count);
                        Decimal cashAppliedAmt = Envs.ZERO;
                        if (noCashlines == 0 && cashList.Count == 0)
                        {
                            C_CashLine_ID = 0;
                            log.Config(" ... no CashLines - TotalApplied=" + totalAppliedAmt);
                            //  Create Allocation
                            log.Fine("C_CashLine_ID=" + C_CashLine_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                + ", Amount=" + AppliedAmt + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                            //	Allocation Header
                            if (alloc.Get_ID() == 0 && !alloc.Save())
                            {
                                log.Log(Level.SEVERE, "Allocation not created");
                                trx.Rollback();
                                trx.Close();
                                return;
                            }
                            //	Allocation Line
                            MAllocationLine aLine = new MAllocationLine(alloc, AppliedAmt,
                                DiscountAmt, WriteOffAmt, OverUnderAmt);
                            aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                            aLine.SetPaymentInfo(0, C_CashLine_ID);
                            if (!aLine.Save(trx.GetTrxName()))
                                log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                            log.Fine("Allocation Amount=" + AppliedAmt);
                        }

                        totalAppliedAmt = Decimal.Add(totalAppliedAmt, AppliedAmt);
                        log.Config("TotalRemaining=" + totalAppliedAmt);
                    }
                }   //  invoice selected
            }   //  invoice loop

            #endregion

            //	Only Payments and total of 0 (e.g. Payment/Reversal)
            #region Reversal Payments
            if (invoiceLines == 0 && paymentList.Count > 0
                && Envs.Signum(paymentAppliedAmt) == 0)
            {
                for (int i = 0; i < paymentList.Count; i++)
                {
                    int C_Payment_ID = Util.GetValueOfInt(paymentList[i]);
                    Decimal PaymentAmt = Util.GetValueOfDecimal(amountList[i]);
                    log.Fine("Payment=" + C_Payment_ID
                            + ", Amount=" + PaymentAmt);// + ", Abs=" + PaymentAbs);

                    //	Allocation Header
                    if (alloc.Get_ID() == 0 && !alloc.Save())
                    {
                        log.Log(Level.SEVERE, "Allocation not created");
                        trx.Rollback();
                        trx.Close();
                        return;
                    }
                    //	Allocation Line
                    MAllocationLine aLine = new MAllocationLine(alloc, PaymentAmt,
                        Envs.ZERO, Envs.ZERO, Envs.ZERO);
                    aLine.SetDocInfo(C_BPartner_ID, 0, 0);
                    aLine.SetPaymentInfo(C_Payment_ID, 0);
                    if (!aLine.Save(trx.GetTrxName()))
                        log.Log(Level.SEVERE, "Allocation Line not saved - Payment=" + C_Payment_ID);
                }
            }	//	onlyPayments
            #endregion

            if (Envs.Signum(totalAppliedAmt) != 0)
                log.Log(Level.SEVERE, "Remaining TotalAppliedAmt=" + totalAppliedAmt);

            //	Should start WF
            if (alloc.Get_ID() != 0)
            {
                alloc.ProcessIt(DocActionVariables.ACTION_COMPLETE);
                alloc.Save();
            }

            //  Test/Set IsPaid for Invoice - requires that allocation is posted
            #region Set Invoice IsPaid
            for (int i = 0; i < rowsInvoice.Count; i++)
            {
                //  Invoice line is selected
                bool boolValue = false;
                bool flag = false;
                Dispatcher.BeginInvoke(delegate
                {
                    boolValue = GetBoolValue(vdgvInvoice, i, 0);
                    flag = true;
                });
                while (!flag)
                {
                    System.Threading.Thread.Sleep(1);
                }
                if (boolValue)
                {
                    // KeyNamePair pp = (KeyNamePair)(((BindableObject)rowsCash[i]).GetValue(2));     //  Value
                    //  Invoice variables
                    int C_Invoice_ID = Util.GetValueOfInt(((BindableObject)rowsInvoice[i]).GetValue("C_Invoice_ID"));
                    String sql = "SELECT invoiceOpen(C_Invoice_ID, 0) "
                        + "FROM C_Invoice WHERE C_Invoice_ID=@param1";
                    Decimal open = Util.GetValueOfDecimal(DB.GetSQLValueBD(trx.GetTrxName(), sql, C_Invoice_ID));
                    if (open != null && Envs.Signum(open) == 0)
                    {
                        sql = "UPDATE C_Invoice SET IsPaid='Y' "
                            + "WHERE C_Invoice_ID=" + C_Invoice_ID;
                        int no = DB.ExecuteQuery(sql, null, trx.GetTrxName());
                        log.Config("Invoice #" + i + " is paid");
                    }
                    else
                        log.Config("Invoice #" + i + " is not paid - " + open);
                }
            }
            #endregion

            //  Test/Set Payment is fully allocated
            #region Set Payment Allocated
            if (rowsPayment.Count > 0)
                for (int i = 0; i < paymentList.Count; i++)
                {
                    int C_Payment_ID = Util.GetValueOfInt(paymentList[i]);
                    MPayment pay = new MPayment(Envs.GetCtx(), C_Payment_ID, trx.GetTrxName());
                    if (pay.TestAllocation())
                    {
                        pay.Save();
                    }
                    log.Config("Payment #" + i + (pay.IsAllocated() ? " not" : " is")
                        + " fully allocated");
                }
            #endregion

            //  Test/Set CashLine is fully allocated
            #region Set CashLine Allocated
            if (rowsCash != null)
            {
                List<Decimal> cashList = new List<Decimal>(rowsCash.Count);
                Decimal cashAppliedAmt = Envs.ZERO;
                for (int i = 0; i < cashList.Count; i++)
                {
                    C_CashLine_ID = Util.GetValueOfInt(cashList[i]);
                    MCashLine cash = new MCashLine(Envs.GetCtx(), C_CashLine_ID, trx.GetTrxName());
                    //if (cash.TestAllocation())
                    {
                        cash.SetIsAllocated(true);
                        cash.Save();
                    }
                    log.Config("Cash #" + i + (cash.IsAllocated() ? " is" : " Not")
                        + " fully allocated");
                }

            }
            #endregion

            paymentList.Clear();
            amountList.Clear();
            trx.Commit();
            trx.Close();

        }

        /// <summary>
        /// Save Data
        /// </summary>

        private void SavePaymentData(BindingSource rowsPayment, BindingSource rowsCash, BindingSource rowsInvoice, DateTime? DateTrx)
        {
            //DateTime? DateTrx = Util.GetValueOfDateTime(vdtpDateField.GetValue());
            //SetBusy(true);

            if (_noInvoices + _noPayments == 0)
                return;

            //  fixed fields
            int AD_Client_ID = Envs.GetCtx().GetContextAsInt(_windowNo, "AD_Client_ID");
            int AD_Org_ID = Envs.GetCtx().GetContextAsInt(_windowNo, "AD_Org_ID");
            int C_BPartner_ID = _C_BPartner_ID;
            int C_Order_ID = 0;
            int C_CashLine_ID = 0;
            //DateTime? DateTrx = Util.GetValueOfDateTime(vdtpDateField.GetValue());
            int C_Currency_ID = _C_Currency_ID;	//	the allocation currency
            //
            if (AD_Org_ID == 0)
            {
                Classes.ShowMessage.Error("Org0NotAllowed", null);
                return;
            }
            //
            log.Config("Client=" + AD_Client_ID + ", Org=" + AD_Org_ID
                + ", BPartner=" + C_BPartner_ID + ", Date=" + DateTrx);

            Trx trx = Trx.Get(Trx.CreateTrxName("AL"), true);

            /**
             * Generation of allocations:               amount/discount/writeOff
             *  - if there is one payment -- one line per invoice is generated
             *    with both the Invoice and Payment reference
             *      Pay=80  Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#1
             *    or
             *      Pay=160 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#1
             *      Pay=160 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#2
             *
             *  - if there are multiple payment lines -- the amounts are allocated
             *    starting with the first payment and payment
             *      Pay=60  Inv=100 Disc=10 WOff=10 =>  60/10/10    Pay#1   Inv#1
             *      Pay=100 Inv=100 Disc=10 WOff=10 =>  20/0/0      Pay#2   Inv#1
             *      Pay=100 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#2   Inv#2
             *
             *  - if you apply a credit memo to an invoice
             *              Inv=10  Disc=0  WOff=0  =>  10/0/0              Inv#1
             *              Inv=-10 Disc=0  WOff=0  =>  -10/0/0             Inv#2
             *
             *  - if you want to write off a (partial) invoice without applying,
             *    enter zero in applied
             *              Inv=10  Disc=1  WOff=9  =>  0/1/9               Inv#1
             *  Issues
             *  - you cannot write-off a payment
             */


            //  Payment - Loop and Add them to paymentList/amountList

            try
            {
                #region Payment-Loop
                //int pRows = vdgvPayment.ItemsSource.OfType<object>().Count();
                //  IList rowsPayment = vdgvPayment.ItemsSource as IList;

                List<int> paymentList = new List<int>(rowsPayment.Count);
                List<Decimal> amountList = new List<Decimal>(rowsPayment.Count);
                Decimal paymentAppliedAmt = Envs.ZERO;
                for (int i = 0; i < rowsPayment.Count; i++)
                {
                    //  Payment line is selected
                    bool boolValue = false;
                    bool flag = false;
                    Dispatcher.BeginInvoke(delegate
                    {
                        boolValue = GetBoolValue(vdgvPayment, i, 0);
                        flag = true;
                    });
                    while (!flag)
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                    if (boolValue)
                    {
                        //KeyNamePair pp = (KeyNamePair)vdgvPayment.Rows[i].Cells[2].Value;
                        // KeyNamePair pp = (KeyNamePair)(((BindableObject)rowsPayment[i]).GetValue(2));   //  Value
                        //  Payment variables
                        int C_Payment_ID = Util.GetValueOfInt(((BindableObject)rowsPayment[i]).GetValue("C_PAYMENT_ID"));
                        paymentList.Add(C_Payment_ID);
                        //
                        // Decimal PaymentAmt = Util.GetValueOfDecimal(vdgvPayment.Rows[i].Cells[_payment].Value);  //  Applied Payment
                        Decimal PaymentAmt = Util.GetValueOfDecimal(((BindableObject)rowsPayment[i]).GetValue(_payment));  //  Applied Payment
                        amountList.Add(PaymentAmt);
                        //
                        paymentAppliedAmt = Decimal.Add(paymentAppliedAmt, PaymentAmt);
                        //
                        log.Fine("C_Payment_ID=" + C_Payment_ID
                            + " - PaymentAmt=" + PaymentAmt); // + " * " + Multiplier + " = " + PaymentAmtAbs);
                    }
                }
                log.Config("Number of Payments=" + paymentList.Count + " - Total=" + paymentAppliedAmt);
                #endregion

                //  Invoices - Loop and generate alloctions
                #region Invoice-Loop with allocation
                // int iRows = vdgvInvoice.ItemsSource.OfType<object>().Count();
                //  IList rowsInvoice=vdgvInvoice.ItemsSource as IList;

                Decimal totalAppliedAmt = Envs.ZERO;

                //	Create Allocation - but don't save yet
                MAllocationHdr alloc = new MAllocationHdr(Envs.GetCtx(), true,	//	manual
                    DateTrx, C_Currency_ID, Envs.GetCtx().GetContext("#AD_User_Name"), trx.GetTrxName());
                alloc.SetAD_Org_ID(AD_Org_ID);

                //	For all invoices
                int invoiceLines = 0;
                for (int i = 0; i < rowsInvoice.Count; i++)
                {
                    //  Invoice line is selected
                    bool boolValue = false;
                    bool flag = false;
                    Dispatcher.BeginInvoke(delegate
                    {
                        boolValue = GetBoolValue(vdgvInvoice, i, 0);
                        flag = true;
                    });
                    while (!flag)
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                    if (boolValue)
                    {
                        invoiceLines++;
                        //  KeyNamePair pp = (KeyNamePair)vdgvInvoice.Rows[i].Cells[2].Value;    //  Value
                        // KeyNamePair pp = (KeyNamePair)(((BindableObject)rowsPayment[i]).GetValue(2));      //  Value
                        //  Invoice variables
                        int C_Invoice_ID = Util.GetValueOfInt(((BindableObject)rowsInvoice[i]).GetValue("C_INVOICE_ID"));
                        //  Decimal AppliedAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_applied].Value);

                        Decimal AppliedAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_applied));
                        //  semi-fixed fields (reset after first invoice)
                        //     Decimal DiscountAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_discount].Value);
                        //    Decimal WriteOffAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_writeOff].Value);

                        Decimal DiscountAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_discount));
                        Decimal WriteOffAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_writeOff));

                        //	OverUnderAmt needs to be in Allocation Currency
                        //     Decimal OverUnderAmt = Decimal.Subtract(Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_open].Value),
                        //        Decimal.Subtract(AppliedAmt, Decimal.Subtract(DiscountAmt, WriteOffAmt)));

                        Decimal OverUnderAmt = Decimal.Subtract(Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_open)),
                        Decimal.Subtract(AppliedAmt, Decimal.Subtract(DiscountAmt, WriteOffAmt)));

                        log.Config("Invoice #" + i + " - AppliedAmt=" + AppliedAmt);// + " -> " + AppliedAbs);

                        //Payment Settelment**********
                        //  loop through all payments until invoice applied
                        int noPayments = 0;
                        for (int j = 0; j < paymentList.Count && Envs.Signum(AppliedAmt) != 0; j++)
                        {
                            int C_Payment_ID = Util.GetValueOfInt(paymentList[j]);
                            Decimal PaymentAmt = Util.GetValueOfDecimal(amountList[j]);
                            if (Envs.Signum(PaymentAmt) != 0)
                            {
                                log.Config(".. with payment #" + j + ", Amt=" + PaymentAmt);
                                noPayments++;
                                //  use Invoice Applied Amt
                                Decimal amount = Envs.ZERO;
                                if ((Math.Abs(AppliedAmt)).CompareTo(Math.Abs(PaymentAmt)) > 0)
                                {
                                    amount = PaymentAmt;
                                }
                                else
                                {
                                    amount = AppliedAmt;
                                }
                                log.Fine("C_Payment_ID=" + C_Payment_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                    + ", Amount=" + amount + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                                //	Allocation Header
                                if (alloc.Get_ID() == 0 && !alloc.Save())
                                {
                                    log.Log(Level.SEVERE, "Allocation not created");
                                    trx.Rollback();
                                    trx.Close();
                                    return;
                                }
                                //	Allocation Line
                                MAllocationLine aLine = new MAllocationLine(alloc, amount,
                                    DiscountAmt, WriteOffAmt, OverUnderAmt);
                                aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                                //aLine.SetPaymentInfo(C_Payment_ID, C_CashLine_ID);
                                aLine.SetPaymentInfo(C_Payment_ID, 0);//cashline for payment allocation is zero
                                if (!aLine.Save())
                                    log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                                //  Apply Discounts and WriteOff only first time
                                DiscountAmt = Envs.ZERO;
                                WriteOffAmt = Envs.ZERO;
                                //  subtract amount from Payment/Invoice
                                AppliedAmt = Decimal.Subtract(AppliedAmt, amount);
                                //AppliedAmt = Decimal.Subtract(PaymentAmt, AppliedAmt);
                                PaymentAmt = Decimal.Subtract(PaymentAmt, amount);
                                log.Fine("Allocation Amount=" + amount + " - Remaining  Applied=" + AppliedAmt + ", Payment=" + PaymentAmt);

                                //amountList.set(j, PaymentAmt);  //  update
                                amountList[j] = PaymentAmt;  //  update//set

                            }	//	for all applied amounts
                        }	//	loop through payments for invoice

                        //  No Payments allocated and none existing (e.g. Inv/CM)

                        if (noPayments == 0 && paymentList.Count == 0)
                        {
                            int C_Payment_ID = 0;
                            log.Config(" ... no payment - TotalApplied=" + totalAppliedAmt);
                            //  Create Allocation
                            log.Fine("C_Payment_ID=" + C_Payment_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                + ", Amount=" + AppliedAmt + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                            //	Allocation Header
                            if (alloc.Get_ID() == 0 && !alloc.Save())
                            {
                                log.Log(Level.SEVERE, "Allocation not created");
                                trx.Rollback();
                                trx.Close();
                                return;
                            }
                            //	Allocation Line
                            MAllocationLine aLine = new MAllocationLine(alloc, AppliedAmt,
                                DiscountAmt, WriteOffAmt, OverUnderAmt);
                            aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                            //aLine.SetPaymentInfo(C_Payment_ID, C_CashLine_ID);
                            aLine.SetPaymentInfo(C_Payment_ID, 0);
                            if (!aLine.Save(trx.GetTrxName()))
                                log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                            log.Fine("Allocation Amount=" + AppliedAmt);
                        }

                        totalAppliedAmt = Decimal.Add(totalAppliedAmt, AppliedAmt);
                        log.Config("TotalRemaining=" + totalAppliedAmt);
                    }   //  invoice selected
                }   //  invoice loop

                #endregion

                //	Only Payments and total of 0 (e.g. Payment/Reversal)
                #region Reversal Payments
                if (invoiceLines == 0 && paymentList.Count > 0
                    && Envs.Signum(paymentAppliedAmt) == 0)
                {
                    for (int i = 0; i < paymentList.Count; i++)
                    {
                        int C_Payment_ID = Util.GetValueOfInt(paymentList[i]);
                        Decimal PaymentAmt = Util.GetValueOfDecimal(amountList[i]);
                        log.Fine("Payment=" + C_Payment_ID
                                + ", Amount=" + PaymentAmt);// + ", Abs=" + PaymentAbs);

                        //	Allocation Header
                        if (alloc.Get_ID() == 0 && !alloc.Save())
                        {
                            log.Log(Level.SEVERE, "Allocation not created");
                            trx.Rollback();
                            trx.Close();
                            return;
                        }
                        //	Allocation Line
                        MAllocationLine aLine = new MAllocationLine(alloc, PaymentAmt,
                            Envs.ZERO, Envs.ZERO, Envs.ZERO);
                        aLine.SetDocInfo(C_BPartner_ID, 0, 0);
                        aLine.SetPaymentInfo(C_Payment_ID, 0);
                        if (!aLine.Save(trx.GetTrxName()))
                            log.Log(Level.SEVERE, "Allocation Line not saved - Payment=" + C_Payment_ID);
                    }
                }	//	onlyPayments
                #endregion

                if (Envs.Signum(totalAppliedAmt) != 0)
                    log.Log(Level.SEVERE, "Remaining TotalAppliedAmt=" + totalAppliedAmt);

                //	Should start WF
                if (alloc.Get_ID() != 0)
                {
                    alloc.ProcessIt(DocActionVariables.ACTION_COMPLETE);
                    alloc.Save();
                }

                //  Test/Set IsPaid for Invoice - requires that allocation is posted
                #region Set Invoice IsPaid
                for (int i = 0; i < rowsInvoice.Count; i++)
                {
                    //  Invoice line is selected
                    bool boolValue = false;
                    bool flag = false;
                    Dispatcher.BeginInvoke(delegate
                    {
                        boolValue = GetBoolValue(vdgvInvoice, i, 0);
                        flag = true;
                    });
                    while (!flag)
                    {
                        System.Threading.Thread.Sleep(1);
                    }
                    if (boolValue)
                    {
                        //KeyNamePair pp = (KeyNamePair)vdgvInvoice.Rows[i].Cells[2].Value;    //  Value
                        // KeyNamePair pp = (KeyNamePair)((BindableObject)rowsInvoice[i]).GetValue(2);    //  Value

                        //  Invoice variables
                        int C_Invoice_ID = Util.GetValueOfInt(((BindableObject)rowsInvoice[i]).GetValue("C_INVOICE_ID"));
                        String sql = "SELECT invoiceOpen(C_Invoice_ID, 0) "
                            + "FROM C_Invoice WHERE C_Invoice_ID=@param1";
                        Decimal open = Util.GetValueOfDecimal(DB.GetSQLValueBD(trx.GetTrxName(), sql, C_Invoice_ID));
                        if (open != null && Envs.Signum(open) == 0)
                        {
                            sql = "UPDATE C_Invoice SET IsPaid='Y' "
                                + "WHERE C_Invoice_ID=" + C_Invoice_ID;
                            int no = DB.ExecuteQuery(sql, null, trx.GetTrxName());
                            log.Config("Invoice #" + i + " is paid");
                        }
                        else
                            log.Config("Invoice #" + i + " is not paid - " + open);
                    }
                }
                #endregion

                //  Test/Set Payment is fully allocated
                #region Set Payment Allocated
                if (rowsPayment.Count > 0)
                    for (int i = 0; i < paymentList.Count; i++)
                    {
                        int C_Payment_ID = Util.GetValueOfInt(paymentList[i]);
                        MPayment pay = new MPayment(Envs.GetCtx(), C_Payment_ID, trx.GetTrxName());
                        if (pay.TestAllocation())
                        {
                            pay.Save();
                        }
                        log.Config("Payment #" + i + (pay.IsAllocated() ? " not" : " is")
                            + " fully allocated");
                    }
                #endregion

                paymentList.Clear();
                amountList.Clear();
                trx.Commit();
                trx.Close();
            }
            catch
            {
                if (trx != null)
                {
                    trx.Rollback();
                    trx.Close();
                    trx = null;
                }
            }
            finally
            {
                if (trx != null)
                {
                    trx.Rollback();
                    trx.Close();
                    trx = null;
                }

            }

        }

        private void SaveCashData(BindingSource rowsPayment, BindingSource rowsCash, BindingSource rowsInvoice, DateTime? DateTrx)
        {
            //  DateTime? DateTrx = Util.GetValueOfDateTime(vdtpDateField.GetValue());
            //// SetBusy(true);


            if (_noInvoices + _noCashLines == 0)
                return;

            //  fixed fields
            int AD_Client_ID = Envs.GetCtx().GetContextAsInt(_windowNo, "AD_Client_ID");
            int AD_Org_ID = Envs.GetCtx().GetContextAsInt(_windowNo, "AD_Org_ID");
            int C_BPartner_ID = _C_BPartner_ID;
            int C_Order_ID = 0;
            int C_CashLine_ID = 0;

            int C_Currency_ID = _C_Currency_ID;	//	the allocation currency
            //
            if (AD_Org_ID == 0)
            {
                Classes.ShowMessage.Error("Org0NotAllowed", null);
                return;
            }
            //
            log.Config("Client=" + AD_Client_ID + ", Org=" + AD_Org_ID
                + ", BPartner=" + C_BPartner_ID + ", Date=" + DateTrx);

            Trx trx = Trx.Get(Trx.CreateTrxName("AL"), true);

            /**
             * Generation of allocations:               amount/discount/writeOff
             *  - if there is one payment -- one line per invoice is generated
             *    with both the Invoice and Payment reference
             *      Pay=80  Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#1
             *    or
             *      Pay=160 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#1
             *      Pay=160 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#1   Inv#2
             *
             *  - if there are multiple payment lines -- the amounts are allocated
             *    starting with the first payment and payment
             *      Pay=60  Inv=100 Disc=10 WOff=10 =>  60/10/10    Pay#1   Inv#1
             *      Pay=100 Inv=100 Disc=10 WOff=10 =>  20/0/0      Pay#2   Inv#1
             *      Pay=100 Inv=100 Disc=10 WOff=10 =>  80/10/10    Pay#2   Inv#2
             *
             *  - if you apply a credit memo to an invoice
             *              Inv=10  Disc=0  WOff=0  =>  10/0/0              Inv#1
             *              Inv=-10 Disc=0  WOff=0  =>  -10/0/0             Inv#2
             *
             *  - if you want to write off a (partial) invoice without applying,
             *    enter zero in applied
             *              Inv=10  Disc=1  WOff=9  =>  0/1/9               Inv#1
             *  Issues
             *  - you cannot write-off a payment
             */

            //  CashLines - Loop and Add them to cashList/CashAmountList
            #region CashLines-Loop
            // int cRows = vdgvCashLines.RowCount;
            // IList rowsCash = vdgvCashLine.ItemsSource as IList;

            List<int> cashList = new List<int>(rowsCash.Count);
            List<Decimal> CashAmtList = new List<Decimal>(rowsCash.Count);
            Decimal cashAppliedAmt = Envs.ZERO;
            for (int i = 0; i < rowsCash.Count; i++)
            {
                //  Payment line is selected
                bool boolValue = false;
                bool flag = false;
                Dispatcher.BeginInvoke(delegate
                {
                    boolValue = GetBoolValue(vdgvCashLine, i, 0);
                    flag = true;
                });
                while (!flag)
                {
                    System.Threading.Thread.Sleep(1);
                }
                if (boolValue)
                {
                    //KeyNamePair pp = (KeyNamePair)vdgvCashLine.Rows[i].Cells[2].Value;   //  Value
                    //KeyNamePair pp = (KeyNamePair)((BindableObject)rowsCash[i]).GetValue(2); //  Value
                    //  Payment variables
                    C_CashLine_ID = Util.GetValueOfInt(((BindableObject)rowsCash[i]).GetValue("C_CASHLINE_ID"));
                    cashList.Add(C_CashLine_ID);
                    //
                    //Decimal PaymentAmt = Util.GetValueOfDecimal(vdgvCashLine.Rows[i].Cells[_payment].Value);  //  Applied Payment
                    Decimal PaymentAmt = Util.GetValueOfDecimal(((BindableObject)rowsCash[i]).GetValue(_payment));  //  Applied Payment
                    CashAmtList.Add(PaymentAmt);
                    //
                    cashAppliedAmt = Decimal.Add(cashAppliedAmt, PaymentAmt);
                    //
                    log.Fine("C_CashLine_ID=" + C_CashLine_ID
                        + " - PaymentAmt=" + PaymentAmt); // + " * " + Multiplier + " = " + PaymentAmtAbs);
                }
            }
            log.Config("Number of Cashlines=" + cashList.Count + " - Total=" + cashAppliedAmt);
            #endregion

            //  Invoices - Loop and generate alloctions
            #region Invoice-Loop with allocation
            // int iRows = vdgvInvoice.RowCount;
            //  IList rowsInvoice = vdgvInvoice.ItemsSource as IList;
            Decimal totalAppliedAmt = Envs.ZERO;

            //	Create Allocation - but don't save yet
            MAllocationHdr alloc = new MAllocationHdr(Envs.GetCtx(), true,	//	manual
                DateTrx, C_Currency_ID, Envs.GetCtx().GetContext("#AD_User_Name"), trx.GetTrxName());
            alloc.SetAD_Org_ID(AD_Org_ID);

            //	For all invoices
            int invoiceLines = 0;
            //for (int i = 0; i < rowsCash.Count; i++)
            for (int i = 0; i < rowsInvoice.Count; i++)
            {
                //  Invoice line is selected
                bool boolValue = false;
                bool flag = false;
                Dispatcher.BeginInvoke(delegate
                {

                    boolValue = GetBoolValue(vdgvInvoice, i, 0);
                    flag = true;

                });
                while (!flag)
                {
                    System.Threading.Thread.Sleep(10);
                }
                if (boolValue)
                {
                    invoiceLines++;
                    //   KeyNamePair pp = (KeyNamePair)vdgvInvoice.Rows[i].Cells[2].Value;    //  Value
                    //  KeyNamePair pp = (KeyNamePair)((BindableObject)rowsInvoice[i]).GetValue(2);    //  Value
                    //  Invoice variables
                    int C_Invoice_ID = Util.GetValueOfInt(((BindableObject)rowsInvoice[i]).GetValue("C_INVOICE_ID"));
                    //Decimal AppliedAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_applied].Value);
                    Decimal AppliedAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_applied));
                    //  semi-fixed fields (reset after first invoice)
                    // Decimal DiscountAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_discount].Value);
                    // Decimal WriteOffAmt = Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_writeOff].Value);

                    Decimal DiscountAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_discount));
                    Decimal WriteOffAmt = Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_writeOff));
                    //	OverUnderAmt needs to be in Allocation Currency
                    //Decimal OverUnderAmt = Decimal.Subtract(Util.GetValueOfDecimal(vdgvInvoice.Rows[i].Cells[_open].Value),
                    //    Decimal.Subtract(AppliedAmt, Decimal.Subtract(DiscountAmt, WriteOffAmt)));

                    Decimal OverUnderAmt = Decimal.Subtract(Util.GetValueOfDecimal(((BindableObject)rowsInvoice[i]).GetValue(_open)),
                        Decimal.Subtract(AppliedAmt, Decimal.Subtract(DiscountAmt, WriteOffAmt)));

                    log.Config("Invoice #" + i + " - AppliedAmt=" + AppliedAmt);// + " -> " + AppliedAbs);

                    //CashLines settelment************
                    //  loop through all payments until invoice applied
                    int noCashlines = 0;
                    for (int j = 0; j < cashList.Count && Envs.Signum(AppliedAmt) != 0; j++)
                    {
                        C_CashLine_ID = Util.GetValueOfInt(cashList[j]);
                        Decimal PaymentAmt = Util.GetValueOfDecimal(CashAmtList[j]);
                        if (Envs.Signum(PaymentAmt) != 0)
                        {
                            log.Config(".. with payment #" + j + ", Amt=" + PaymentAmt);
                            noCashlines++;
                            //  use Invoice Applied Amt
                            Decimal amount = AppliedAmt;
                            log.Fine("C_CashLine_ID=" + C_CashLine_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                + ", Amount=" + amount + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                            //	Allocation Header
                            if (alloc.Get_ID() == 0 && !alloc.Save())
                            {
                                log.Log(Level.SEVERE, "Allocation not created");
                                trx.Rollback();
                                trx.Close();
                                return;
                            }
                            //	Allocation Line
                            MAllocationLine aLine = new MAllocationLine(alloc, amount,
                                DiscountAmt, WriteOffAmt, OverUnderAmt);
                            aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                            aLine.SetPaymentInfo(0, C_CashLine_ID);//payment for payment allocation is zero
                            if (!aLine.Save())
                                log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                            //  Apply Discounts and WriteOff only first time
                            DiscountAmt = Envs.ZERO;
                            WriteOffAmt = Envs.ZERO;
                            //  subtract amount from Payment/Invoice
                            AppliedAmt = Decimal.Subtract(AppliedAmt, amount);
                            //AppliedAmt = Decimal.Subtract(PaymentAmt, AppliedAmt);
                            PaymentAmt = Decimal.Subtract(PaymentAmt, amount);
                            log.Fine("Allocation Amount=" + amount + " - Remaining  Applied=" + AppliedAmt + ", Payment=" + PaymentAmt);

                            //amountList.set(j, PaymentAmt);  //  update
                            if (CashAmtList.Count > 0)
                            {
                                MCashLine cline = new MCashLine(Envs.GetCtx(), C_CashLine_ID, null);
                                cline.SetAmount(Decimal.Subtract(cline.GetAmount(), CashAmtList[j]));
                                if (!cline.Save())
                                {
                                    log.SaveError("AmountIsNotUpdated" + C_CashLine_ID.ToString(), "");
                                }
                                CashAmtList[j] = PaymentAmt;  //  update//set
                            }

                        }	//	for all applied amounts
                    }	//	loop through Cash for invoice(Charge)

                    //  No Cashlines allocated and none existing 
                    if (rowsCash.Count > 0)
                        if (noCashlines == 0 && cashList.Count == 0)
                        {
                            C_CashLine_ID = 0;
                            log.Config(" ... no CashLines - TotalApplied=" + totalAppliedAmt);
                            //  Create Allocation
                            log.Fine("C_CashLine_ID=" + C_CashLine_ID + ", C_Invoice_ID=" + C_Invoice_ID
                                + ", Amount=" + AppliedAmt + ", Discount=" + DiscountAmt + ", WriteOff=" + WriteOffAmt);

                            //	Allocation Header
                            if (alloc.Get_ID() == 0 && !alloc.Save())
                            {
                                log.Log(Level.SEVERE, "Allocation not created");
                                trx.Rollback();
                                trx.Close();
                                return;
                            }
                            //	Allocation Line
                            MAllocationLine aLine = new MAllocationLine(alloc, AppliedAmt,
                                DiscountAmt, WriteOffAmt, OverUnderAmt);
                            aLine.SetDocInfo(C_BPartner_ID, C_Order_ID, C_Invoice_ID);
                            aLine.SetPaymentInfo(0, C_CashLine_ID);
                            if (!aLine.Save(trx.GetTrxName()))
                                log.Log(Level.SEVERE, "Allocation Line not written - Invoice=" + C_Invoice_ID);

                            log.Fine("Allocation Amount=" + AppliedAmt);
                        }
                    totalAppliedAmt = Decimal.Add(totalAppliedAmt, AppliedAmt);
                    log.Config("TotalRemaining=" + totalAppliedAmt);
                }   //  invoice selected
            }   //  invoice loop

            #endregion

            if (Envs.Signum(totalAppliedAmt) != 0)
                log.Log(Level.SEVERE, "Remaining TotalAppliedAmt=" + totalAppliedAmt);

            //	Should start WF
            if (alloc.Get_ID() != 0)
            {
                alloc.ProcessIt(DocActionVariables.ACTION_COMPLETE);
                alloc.Save();
            }

            //  Test/Set IsPaid for Invoice - requires that allocation is posted
            #region Set Invoice IsPaid
            for (int i = 0; i < rowsInvoice.Count; i++)
            {
                bool boolValue = false;
                //  Invoice line is selected
                bool flag = false;
                Dispatcher.BeginInvoke(delegate
                {
                    boolValue = GetBoolValue(vdgvInvoice, i, 0);
                    flag = true;
                    SetBusy(false);
                });
                while (!flag)
                {
                    System.Threading.Thread.Sleep(1);
                }
                if (boolValue)
                {
                    //KeyNamePair pp = (KeyNamePair)vdgvInvoice.Rows[i].Cells[2].Value;    //  Value
                    //KeyNamePair pp = (KeyNamePair)((BindableObject)rowsInvoice[i]).GetValue(2);    //  Value
                    //  Invoice variables
                    int C_Invoice_ID = Util.GetValueOfInt(((BindableObject)rowsInvoice[i]).GetValue("C_INVOICE_ID"));
                    String sql = "SELECT invoiceOpen(C_Invoice_ID, 0) "
                        + "FROM C_Invoice WHERE C_Invoice_ID=@param1";
                    Decimal open = Util.GetValueOfDecimal(DB.GetSQLValueBD(trx.GetTrxName(), sql, C_Invoice_ID));
                    if (open != null && Envs.Signum(open) == 0)
                    {
                        sql = "UPDATE C_Invoice SET IsPaid='Y' "
                            + "WHERE C_Invoice_ID=" + C_Invoice_ID;
                        int no = DB.ExecuteQuery(sql, null, trx.GetTrxName());
                        log.Config("Invoice #" + i + " is paid");
                    }
                    else
                        log.Config("Invoice #" + i + " is not paid - " + open);
                }
            }
            #endregion

            //  Test/Set CashLine is fully allocated
            #region Set CashLine Allocated
            if (rowsCash.Count > 0)
                for (int i = 0; i < cashList.Count; i++)
                {
                    C_CashLine_ID = Util.GetValueOfInt(cashList[i]);
                    MCashLine cash = new MCashLine(Envs.GetCtx(), C_CashLine_ID, trx.GetTrxName());
                    if (cash.GetAmount() == 0)
                    {
                        cash.SetIsAllocated(true);
                        cash.Save();
                    }
                    log.Config("Cash #" + i + (cash.IsAllocated() ? " not" : " is")
                       + " fully allocated");
                }
            #endregion

            cashList.Clear();
            CashAmtList.Clear();
            trx.Commit();
            trx.Close();
            //SetBusy(false);

        }

        #region "BackGround Worker"
        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {

            MPayment.SetIsAllocated(Envs.GetCtx(), _C_BPartner_ID, null);
            MInvoice.SetIsPaid(Envs.GetCtx(), _C_BPartner_ID, null);

        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            log.Info("InvoicePaid and Allocation set against--" + _C_BPartner_ID);
        }

        #endregion

        private void vbPartnerSearch_VetoableChangeListener(object sender, EventArgs e)
        {
            SetBusy(true);
            VetoableChange(vbPartnerSearch.GetName(), vbPartnerSearch.GetValue());
        }

        private void cmbCurrencyPick_SelectedIndexChanged(object sender, EventArgs e)
        {
            VetoableChange(cmbCurrencyPick.GetSelectedText(), cmbCurrencyPick.SelectedValue);
            VetoableChange("C_Currency_ID", ((KeyNamePair)cmbCurrencyPick.SelectedItem).Key);
        }

        private void chkMultiCurrency_VetoableChangeListener(object sender, EventArgs e)
        {
            VetoableChange(vchkMultiCurrency.Name, vchkMultiCurrency.GetValue());
            LoadBPartner();
        }

        private void vdtpDateField_VetoableChangeListener(object sender, EventArgs e)
        {
            VetoableChange("Date", vdtpDateField.Value);
        }

        private void vbtnAllocate_Click(object sender, RoutedEventArgs e)
        {
            BindingSource rowsPayment = vdgvPayment.ItemsSource as BindingSource;
            BindingSource rowsCash = vdgvCashLine.ItemsSource as BindingSource;
            BindingSource rowsInvoice = vdgvInvoice.ItemsSource as BindingSource;
            vbtnAllocate.IsEnabled = false;
            bool checkallo = (bool)vchkAllocation.IsChecked;
            DateTime? DateTrx = Util.GetValueOfDateTime(vdtpDateField.GetValue());
            SetBusy(true);
            txtBusy.Text = Msg.GetMsg("Processing");
            ///vbtnAllocate.IsEnabled = false;
            System.Threading.ThreadPool.QueueUserWorkItem(delegate
            {
                //SaveData(rowsPayment, rowsCash, rowsInvoice, DateTrx);
                if (checkallo)
                {
                    SaveCashData(rowsPayment, rowsCash, rowsInvoice, DateTrx);
                }
                else
                {
                    SavePaymentData(rowsPayment, rowsCash, rowsInvoice, DateTrx);
                }
                Dispatcher.BeginInvoke(() => LoadBPartner());

            });
          //  LoadBPartner();
            vbtnAllocate.IsEnabled = true;
        }

        //private void chkAllocation_CheckStateChanged(object sender, EventArgs e)
        //{
        //    if ((bool)vchkAllocation.IsChecked)
        //    {
        //        vdgvCashLine.IsReadOnly = false;
        //        vdgvPayment.IsReadOnly = true;
        //        IList rowSource = vdgvPayment.ItemsSource as IList;
        //        for (int i = 0; i < rowSource.Count; i++)
        //        {
        //            bool boolValue = GetBoolValue(vdgvPayment, i, 0);
        //            if (boolValue)
        //            {
        //                ((BindableObject)rowSource[i]).SetValue(0, false.ToString());
        //                ((BindableObject)rowSource[i]).SetValue("AppliedAmt", 0.ToString());
        //                // vdgvPayment.Rows[i].Cells[0].Value = false;
        //                // vdgvPayment.Rows[i].Cells["AppliedAmt"].Value = 0;
        //            }
        //        }
        //    }
        //    else
        //    {
        //        vdgvCashLine.IsReadOnly = true;
        //        vdgvPayment.IsReadOnly = false;
        //        IList rowSource = vdgvCashLine.ItemsSource as IList;
        //        for (int i = 0; i < rowSource.Count; i++)
        //        {
        //            bool boolValue = GetBoolValue(vdgvCashLine, i, 0);
        //            if (boolValue)
        //            {
        //                ((BindableObject)rowSource[i]).SetValue(0, false.ToString());
        //                ((BindableObject)rowSource[i]).SetValue("AppliedAmt", 0.ToString());
        //                //.Rows[i].Cells[0].Value = false;
        //                // vdgvCashLine.Rows[i].Cells["AppliedAmt"].Value = 0;
        //            }
        //        }
        //    }
        //}

        public int ColumnIndex(DataGrid gridView, String colName)
        {
            int j = -1;
            for (int i = 0; i < gridView.Columns.Count; i++)
            {
                if (gridView.Columns[i].Header.ToString() == colName)
                {
                    j = i;
                }
            }
            return j;
        }

        private void vchkMultiCurrency_Click(object sender, RoutedEventArgs e)
        {
            VetoableChange(vchkMultiCurrency.Name, vchkMultiCurrency.GetValue());
            LoadBPartner();
        }

        private void vchkAllocation_Click(object sender, RoutedEventArgs e)
        {
            BindingSource rowsPayment = vdgvPayment.ItemsSource as BindingSource;
            BindingSource rowsCash = vdgvCashLine.ItemsSource as BindingSource;
            if ((bool)vchkAllocation.IsChecked)
            {
                vdgvCashLine.IsReadOnly = false;
                vdgvPayment.IsReadOnly = true;
                if (rowsPayment!=null)
                {
                    // for (int i = 0; i < vdgvPayment.RowCount; i++)
                    for (int i = 0; i < rowsPayment.Count; i++)
                    {
                        bool boolValue = GetBoolValue(vdgvPayment, i, 0);
                        if (boolValue)
                        {
                            chk.SetCheckValue = false;
                            chk.IsReadOnly = true;
                            ((BindableObject)((ObservableCollection<object>)vdgvPayment.ItemsSource)[i]).SetValue("SELECTROW", "false");
                            ((BindableObject)vdgvPayment.SelectedItem).SetValue("SELECTROW", "false");
                            ((BindableObject)rowsPayment[i]).SetValue(0, false.ToString());
                            ((BindableObject)rowsPayment[i]).SetValue("AppliedAmt", 0.ToString());
                            //vdgvPayment.
                            //vdgvPayment.Rows[i].Cells[0].Value = false;
                            //vdgvPayment.Rows[i].Cells["AppliedAmt"].Value = 0;
                        }
                    }
                }
            }
            else
            {
                vdgvCashLine.IsReadOnly = true;
                vdgvPayment.IsReadOnly = false;
                if (rowsCash != null)
                {
                    for (int i = 0; i < rowsCash.Count; i++)
                    {
                        bool boolValue = GetBoolValue(vdgvCashLine, i, 0);
                        if (boolValue)
                        {
                            //if (chkCash.Checked != null)
                            //{
                            //    chkCash.SetCheckValue = false;
                            //}
                            ((BindableObject)vdgvCashLine.SelectedItem).SetValue("SELECTROW", "false");
                            ((BindableObject)rowsCash[i]).SetValue(0, false.ToString());
                            ((BindableObject)rowsCash[i]).SetValue("AppliedAmt", 0.ToString());
                            //vdgvCashLines.Rows[i].Cells[0].Value = false;
                            //vdgvCashLines.Rows[i].Cells["AppliedAmt"].Value = 0;
                        }
                    }
                }
                else
                {
                    chk.SetCheckValue = false;
                    chk.IsReadOnly = false;
                }
            }
        }

        private void vdgvCashLine_CellEditEnded(object sender, DataGridCellEditEndedEventArgs e)
        {
            if (vdgvCashLine.IsReadOnly)
            {
                return;
            }
            BindingSource rowSource = vdgvCashLine.ItemsSource as BindingSource;
            //if (e.Column.DisplayIndex == vdgvCashLine.Rows[e.RowIndex].Cells["AppliedAmt"].ColumnIndex)
            if (e.Column.DisplayIndex == ColumnIndex(vdgvCashLine, "AppliedAmount"))
            {
                //logic to not set greater appliedAmount then open amount
                // if (Util.GetValueOfDecimal(vdgvCashLine.Rows[e.RowIndex].Cells["OpenAmt"].Value) >= Util.GetValueOfDecimal(vdgvCashLine.Rows[e.RowIndex].Cells["AppliedAmt"].Value))
                if (Util.GetValueOfDecimal(((BindableObject)rowSource[e.Row.GetIndex()]).GetValue("OpenAmt")) >= Util.GetValueOfDecimal(((BindableObject)rowSource[e.Row.GetIndex()]).GetValue("AppliedAmount")))
                {

                }
                else
                {
                    // vdgvCashLine.Rows[e.RowIndex].Cells["AppliedAmt"].Value = vdgvCashLine.Rows[e.RowIndex].Cells["PaidAmount"].Value;
                    ((BindableObject)rowSource[e.Row.GetIndex()]).SetValue(ColumnIndex(vdgvCashLine, "AppliedAmt"), ((BindableObject)rowSource[e.Row.GetIndex()]).GetValue("PaidAmount"));
                }
                isUpdate = true;
                TableChanged(e.Row.GetIndex(), e.Column.DisplayIndex, true, true);
                isUpdate = false;
            }
        }

        private void vdgvPayment_CellEditEnded(object sender, DataGridCellEditEndedEventArgs e)
        {
            BindingSource rowSource = vdgvPayment.ItemsSource as BindingSource;
            if (vdgvPayment.IsReadOnly)
            {
                return;
            }
            if (e.Column.DisplayIndex == ColumnIndex(vdgvPayment, "AppliedAmount"))
            {
                //logic to not set greater appliedAmount then open amount
                // if (Util.GetValueOfDecimal(vdgvPayment.Rows[e.RowIndex].Cells["OpenAmt"].Value) >= Util.GetValueOfDecimal(vdgvPayment.Rows[e.RowIndex].Cells["AppliedAmt"].Value))
                if (Util.GetValueOfDecimal(((BindableObject)rowSource[e.Row.GetIndex()]).GetValue("OpenAmt")) >= Util.GetValueOfDecimal(((BindableObject)rowSource[e.Row.GetIndex()]).GetValue("AppliedAmt")))
                { }
                else
                {
                    //vdgvPayment.Rows[e.RowIndex].Cells["AppliedAmt"].Value = vdgvPayment.Rows[e.RowIndex].Cells["OpenAmt"].Value;
                    ((BindableObject)rowSource[e.Row.GetIndex()]).SetValue(ColumnIndex(vdgvCashLine, "AppliedAmt"), ((BindableObject)rowSource[e.Row.GetIndex()]).GetValue("OpenAmt"));
                }
                isUpdate = true;
                TableChanged(e.Row.GetIndex(), e.Column.DisplayIndex, false, false);
                isUpdate = false;

            }
        }

        private void vdgvInvoice_CellEditEnded(object sender, DataGridCellEditEndedEventArgs e)
        {
            if (e.Column.DisplayIndex == ColumnIndex(vdgvInvoice, "Discount %")
               || e.Column.DisplayIndex == ColumnIndex(vdgvInvoice, "WriteOff")
               || e.Column.DisplayIndex == ColumnIndex(vdgvInvoice, "AppliedAmount"))
            {
                isUpdate = true;
                TableChanged(e.Row.GetIndex(), e.Column.DisplayIndex, true, false);
                isUpdate = false;
            }
        }

        private void vdgvCashLine_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void vdgvInvoice_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {

        }

        private void busyWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            e.Handled = true;
        }

    }
}

